如何更深入地使用libxml2解析xml文件
问题描述:
我在深入解析xml文件时遇到了问题。为了简单起见,我们假设我有这样的XML文件结构,在xmlsoft.org提供:如何更深入地使用libxml2解析xml文件
<?xml version="1.0"?>
<story>
<storyinfo>
<author>John Fleck</author>
<datewritten>June 2, 2002</datewritten>
<keyword>example keyword</keyword>
</storyinfo>
<body>
<headline>This is the headline</headline>
<para>This is the body text.</para>
</body>
</story>
为了检索XML的一致好评文件中的每个关键字,开发商的目的此解决方案:
#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;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))) {
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;
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return;
}
if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {
fprintf(stderr,"document of the wrong type, root node != story");
xmlFreeDoc(doc);
return;
}
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
parseStory (doc, cur);
}
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);
}
我的疑问是:如果,例如,<storyinfo>
有另外的属性一样
<storyinfo>
...
<rev>
<id> 26546 </id>
</rev>
</storyinfo>
我怎么能访问/的printf(EG)<id>
从<rev>
?底线,再一次,我怎么能越来越深入得到我想要的?对于上面的例子,我试过了,没有成功:
之前xmlFreeDoc释放(DOC)行parseDoc功能添加此
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"rev"))){
parseRev (doc, cur);
}
cur = cur->next;
}
创建一个新的功能,parseRev(xmlDocPtr DOC,的xmlNodePtr CUR):
void
parseRev (xmlDocPtr doc, xmlNodePtr cur) {
xmlChar *key;
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"id"))) {
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
printf("id: %s\n", key);
xmlFree(key);
}
cur = cur->next;
}
return;
}
我该如何做到这一点?
答
似乎缺少的重要细节:当您通过按照cur-> next迭代每个孩子时,它只使用IMMEDIATE子元素。对子女story
迭代会给你storyinfo
和storybody
,没有别的。
上parseDoc功能之前xmlFreeDoc释放(DOC)线
你不想做,在parseDoc一个storyinfo
里面添加这个,因为rev
生活。将此检查添加到迭代storyinfo
的子项时,它应该可以工作。
只需使用'storyinfo'节点从'parseStory'调用'parseRev'即可。 – nwellnhof