2012-07-08 83 views
0

今天我第一次开始学习libxml。并一直努力寻找肥皂响应的根节点。该死的挣扎。无法在xml中获取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; 

}

如前所述,我努力找出根节点。 它说“错误类型根节点的文档!=” 谢谢。

回答

2

您遇到的问题是“soapenv:Envelope”不是节点的名称。该名称仅仅是“soapenv”别名引用的名称空间中的“Envelope”。

命名空间是什么让你困惑在这里。

附录:

你已经有根节点。你在开始的时候有它:

cur = xmlDocGetRootElement (doc); 

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。

因此,最终,您的根节点将是类型1元素,其名称为Envelope(cur-> name),一个href为http://schemas.xmlsoap.org/soap/envelope/(cur-> ns-> href)的名称空间,前缀为soapenv(cur-> ns->前缀)。命名空间前缀不是命名空间。您无法比较节点的前缀,并期望比较名称空间。命名空间由href标识。前缀是一种简写,即使对于相同的名称空间,它也可以从一个节点变为另一个节点(它往往不是,但它可以,尤其是在导入其他XML文档时)。

+0

好的。但是,这种xml缓冲区的根节点是什么?我怎样才能得到根节点? – sach 2012-07-08 14:32:12