[英]XML Parsing results in Duplicates using libxml2
我正在使用libxml2解析以下XML字符串:
<?xml version=\"1.0\"?>
<note>
<to>
<name>Tove</name>
<name>Tovi</name>
</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
格式化为C风格的字符串:
"<?xml version=\"1.0\"?><note><to><name>Tove</name><name>Tovi</name></to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>"
这是基于W3C网站上有关XML的示例。 我只在“到”字段中添加了嵌套名称。
我在C ++中具有以下递归代码,将其解析为对象树:
RBCXMLNode * RBCXMLDoc::recursiveProcess(xmlNodePtr node) {
RBCXMLNode *rNode = new RBCXMLNode();
xmlNodePtr childIterator = node->xmlChildrenNode;
const char *chars = (const char *)(node->name);
string name(chars);
const char *content = (const char *)xmlNodeGetContent(node);
rNode->setName(name);
rNode->setUTF8Data(content);
cout << "Just parsed " << rNode->name() << ": " << rNode->stringData() << endl;
while (childIterator != NULL) {
RBCXMLNode *rNode2 = recursiveProcess(childIterator);
rNode->addChild(rNode2);
childIterator = childIterator->next;
}
return rNode;
}
因此,它为每个节点创建匹配的对象,设置其名称和内容,然后为其子代递归。 请注意,每个节点仅处理一次。 但是,我得到以下(至少对我来说是荒谬的)输出:
只是分析了笔记:ToveToviJaniReminder这个周末别忘了我!
刚刚解析为:ToveTovi
刚解析的名称:Tove
刚解析的文字:托夫
刚刚解析过的名字:Tovi
刚刚解析的文本:Tovi
刚刚从解析:Jani
刚刚解析的文本:Jani
刚解析标题:提醒
刚解析的文字:提醒
只是剖析了身体:这个周末别忘了我!
刚解析的文字:本周末不要忘记我!
请注意,每个项目都要被解析两次; 一旦将名称命名为“文本”,并将其命名为“应该是什么”。 同样,“ note”根节点也正在解析其数据。 这是不可取的。 另请注意,此根节点不会像其他节点一样被解析两次。
所以我有两个问题:
提前致谢。
我在你的代码中看到的主要问题是你正在调用xmlNodeGetContent()
。 这将返回标签内部的整个文本及其结尾对应部分。
使用libxml2解析时,您会得到一些内容复杂的节点,因此您不能依赖xmlNodeGetContent()
来检索内容。 您必须以不同方式执行递归功能。 例如,对您的函数而言,最快的解决方案是仅打印非文本节点的节点名称(使用xmlNodeIsText()
测试),并仅为文本节点编写xmlNodeGetContent()
。 这会给你一个类似的输出:
Just parsed note
Just parsed to
Just parsed name
Just parsed text: Tove
Just parsed name
Just parsed text: Tovi
...
请注意,现在您只打印元素, 并且只有文本元素类型时才显示文本。
从概念上讲,这也是有意义的,因为非文本节点(非文本)的内容是如此复杂,以至于您如何打印它? 您只能打印其标签(名称)。 但是,文本节点非常简单,您可以打印其内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.