今天我第一次开始学习libxml。并一直在努力寻找肥皂反应的根节点。该死的挣扎。
这是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><mms.smil></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;
}
如上所述,我正在努力寻找根节点。 它的说法是“错误类型根节点的文件!=” 感谢。
答案 0 :(得分: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中有几个“节点类型”,最值得注意的是Type 1(它们是元素)和Type 3(它们是元素之间的文本)。此代码检查类型1以打印出名称和前缀。但是请注意,无论节点类型如何,它都会盲目地调用子节点上的dumpNode。
因此,最后,您的根节点将是Type 1元素,名称为Envelope
(cur-> name),href为http://schemas.xmlsoap.org/soap/envelope/
的命名空间(cur- &gt; ns-&gt; href),前缀为soapenv
(cur-> ns->前缀)。名称空间前缀不是名称空间。您无法比较节点的前缀并期望比较命名空间。在这种情况下,命名空间由href标识。前缀是一种简写,并且可以在节点之间进行更改,即使对于相同的命名空间也是如此(它往往不会,但它可以,尤其是在您导入其他XML文档时)。