0

今日、私は初めて libxml を学び始めました。そして、SOAP 応答のルート ノードを見つけるのに苦労し続けました。くそー苦労した。

これはxmlバッファです

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sti_xsd="http://www.openmobilealliance.org/schema/sti/v1_0" xsi:type="soapenv:Envelope">
    <soapenv:Body>
        <sti_xsd:TranscodingResponse>
            <sti_xsd:originatorID>test</sti_xsd:originatorID>
            <sti_xsd:operationID>1.0</sti_xsd:operationID>
            <sti_xsd:mainReturnResult>
                <sti_xsd:returnCode>2000</sti_xsd:returnCode>
                <sti_xsd:returnString>All 1 transcoding job(s) succeeded</sti_xsd:returnString>
            </sti_xsd:mainReturnResult>
            <sti_xsd:totalDuration>121</sti_xsd:totalDuration>
            <sti_xsd:jobResult>
                <sti_xsd:jobID>JOB26</sti_xsd:jobID>
                <sti_xsd:extensionData>
                    <sti_xsd:property>
                        <sti_xsd:name>van.sti.trx.MemoryUsage</sti_xsd:name>
                        <sti_xsd:value>3568808</sti_xsd:value>
                    </sti_xsd:property>
                </sti_xsd:extensionData>
                <sti_xsd:mainReturnResult>
                    <sti_xsd:returnCode>2000</sti_xsd:returnCode>
                    <sti_xsd:returnString>Successful TranscodingJob (200): Success</sti_xsd:returnString>
                </sti_xsd:mainReturnResult>
                <sti_xsd:duration>119</sti_xsd:duration>
                <sti_xsd:output>
                    <sti_xsd:contentType>application/vnd.wap.mms-message</sti_xsd:contentType>
                    <sti_xsd:contentTypeParams>
                        <sti_xsd:property>
                            <sti_xsd:name>type</sti_xsd:name>
                            <sti_xsd:value>application/smil</sti_xsd:value>
                        </sti_xsd:property>
                        <sti_xsd:property>
                            <sti_xsd:name>start</sti_xsd:name>
                            <sti_xsd:value>&lt;mms.smil&gt;</sti_xsd:value>
                        </sti_xsd:property>
                    </sti_xsd:contentTypeParams>
                    <sti_xsd:location>cid:133699816987026.JOB26</sti_xsd:location>
                    <sti_xsd:mediaSize>40693</sti_xsd:mediaSize>
                </sti_xsd:output>
            </sti_xsd:jobResult>
            <sti_xsd:extensionData>
                <sti_xsd:property>
                    <sti_xsd:name>van.sti.trx.session.id</sti_xsd:name>
                    <sti_xsd:value>STI/gesti05/120514_14h/STI17_23m12s214_00</sti_xsd:value>
                </sti_xsd:property>
                <sti_xsd:property>
                    <sti_xsd:name>van.sti.server.hostname</sti_xsd:name>
                    <sti_xsd:value>getrx01</sti_xsd:value>
                </sti_xsd:property>
            </sti_xsd:extensionData>
        </sti_xsd:TranscodingResponse>
    </soapenv:Body>
</soapenv:Envelope>

以下は私のコードです:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

void parseStory ( xmlDocPtr doc, xmlNodePtr cur )
{

        xmlChar *key;
        cur = cur -> xmlChildrenNode;
        printf ( "Here\n" );
        while ( cur != NULL )
        {   
                if ( ( !xmlStrcmp ( cur -> name, ( const xmlChar * ) "returnCode" ) ) ) 
                {   
                        key = xmlNodeListGetString ( doc, cur -> xmlChildrenNode,1);
                        printf ( "keyword: %s\n", key );
                        xmlFree ( key );
                }   
                cur = cur -> next;
        }   
        return ;
}

static void parseDoc ( char *docname )
{
        xmlDocPtr doc;
        xmlNodePtr cur;
        doc = xmlParseFile ( docname );

        if ( doc == NULL )
        {   
                fprintf ( stderr, "Document not parsed successfully. \n" );
                return;
        }   
        printf ( "Parsing Successful\n" );
        cur = xmlDocGetRootElement ( doc );

        if ( cur == NULL )
        {   
                fprintf ( stderr, "empty document \n" );
                xmlFreeDoc ( doc );
                    printf ( "Got the root Node\n" );
        if ( xmlStrcmp ( cur->name, ( const xmlChar * ) "soapenv:Envelope" ) )
        {
                fprintf ( stderr, "Document of the wrong type root node != ");
                xmlFreeDoc(doc);
                return;

        }

        printf ( "Got the root \n" );
        cur = cur -> xmlChildrenNode;
        while ( cur != NULL )
        {
                if (cur->type == XML_ELEMENT_NODE) {

                                printf ( "Inside if  \n" );
                        if ( !(xmlStrcmp ( cur->name, ( const xmlChar * ) "mainReturnResult" ) ) )
                        {
                                printf ( "Inside \n" );
                                parseStory ( doc, cur );
                        }
                        cur = cur -> xmlChildrenNode;
                        continue;
                }
                cur = cur -> next;
        }

        xmlFreeDoc ( doc );
        return;
}

int main ( int argc, char **argv )
{
        char *docname;

        if ( argc <= 1 )
        {
                printf ( "Usage: %s docname\n", argv[0] );
                return ( 0 );
        }
        docname = argv [1];
        parseDoc ( docname );

        return ( 1 );
}
   return;

}

述べたように、ルートノードを見つけるのに苦労しています。「間違ったタイプのルートノードのドキュメント!=」と言っています ありがとう。

4

1 に答える 1

2

あなたが抱えている問題は、「soapenv:Envelope」がノードの名前ではないことです。この名前は、「soapenv」エイリアスによって参照されるネームスペース内の単に「Envelope」です。

ここであなたを混乱させているのは名前空間です。

補遺:

すでにルート ノードがあります。あなたはそれを最初に持っています:

cur = xmlDocGetRootElement ( doc );

IS はルートcurノードです。

直後に行う場合:

printf("Name = %s\n", cur->name);

「封筒」が表示されますが、これは正しいです。

ドキュメントの要素をダンプする簡単な例を次に示します。割り当てた直後に呼び出すとcur、基本的にツリーをダンプすることがわかります。

static void dumpNode (int indent, xmlNodePtr node) {
    while(node != NULL) {
        if (node->type == 1) {
            int i;
            for(i = 0; i < indent; i++) {
                printf("  ");
            }
            printf("%s : %s\n", node->ns->prefix, node->name);
        }
        dumpNode(indent + 1, node->children);
        node = node->next;
    }
}

libxml にはいくつかの「ノード タイプ」があることに注意してください。最も顕著なのは、要素であるタイプ 1 と、要素間のテキストであるタイプ 3 です。このコードは、タイプ 1 をチェックして、名前とプレフィックスを出力します。ただし、ノードの種類に関係なく、子の dumpNode をやみくもに呼び出すことにも注意してください。

したがって、最終的に、ルート ノードは、名前がEnvelope(cur->name)、href がhttp://schemas.xmlsoap.org/soap/envelope/(cur->ns->href)、プレフィックスがsoapenv( cur->) のタイプ 1 要素になります。 >ns->プレフィックス)。名前空間プレフィックスは名前空間ではありません。ノードのプレフィックスを比較することはできず、名前空間を比較することを期待できません。名前空間は、この場合、href によって識別されます。接頭辞は省略形であり、同じ名前空間であってもノードごとに変わる可能性があります (そうではない傾向がありますが、特に他の XML ドキュメントをインポートしている場合は可能です)。

于 2012-07-08T14:29:57.300 に答える