【问题标题】:How to go deeper on parsing xml file using libxml2如何更深入地使用 libxml2 解析 xml 文件
【发布时间】:2017-08-08 03:45:58
【问题描述】:

我在深入解析 xml 文件时遇到问题。为简单起见,假设我有 xmlsoft.org 中提供的这个 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);
}

我的疑问是:例如,&lt;storyinfo&gt; 是否有另一个属性,例如

<storyinfo>
...
    <rev>
        <id> 26546 </id>  
    </rev>
</storyinfo>

我如何从&lt;rev&gt; 访问/ printf(例如)&lt;id&gt;?归根结底,再一次,我怎样才能越来越深入地得到我想要的东西?对于上面的例子,我试过了,没有成功:

在 parseDoc 函数的 xmlFreeDoc(doc) 行之前添加这个

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;
}

我怎样才能做到这一点?

【问题讨论】:

  • 只需使用 storyinfo 节点从 parseStory 调用 parseRev。

标签: c xml parsing libxml2


【解决方案1】:

似乎缺少的重要细节:当您通过执行以下 cur->next 迭代每个孩子时,它只使用 IMMEDIATE 孩子。对子代story 进行迭代将得到storyinfo 和storybody,仅此而已。

在 parseDoc 函数的 xmlFreeDoc(doc) 行之前添加这个

您不想在 parseDoc 中这样做,因为 rev 位于 storyinfo 中。当您迭代 storyinfo 的孩子时添加此检查,它应该可以工作。

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    相关资源
    最近更新 更多