libxml2 解析来自不同父节点的相似节点

libxml2 parse similar nodes from different parent nodes

我有一个具有以下结构的 XML 文件(针对此问题进行了简化):

<SuperNode>
  <MediumNode Enable="YES">
    <Child attr1="1" />
    <Child attr1="2" />
    <Child attr1="3" />
  </MediumNode>
  <MediumNode Enable="YES">
    <Child attr1="4" />
    <Child attr1="5" />
  </MediumNode>
</SuperNode>

我使用以下逻辑在 C 中用 libxml2 解析它(为简单起见省略了错误检查),我从他们的 website 的 libxml2 示例中获取了这个逻辑。我需要遍历所有“MediumNode”节点的“Child”节点的所有属性:

xmlDocPtr doc = xmlParseFile("/path/to/xml");     /* check for errors */
xmlXPathContextPtr ctx = xmlXPathNewContext(doc); /* check for errors */
xmlXPathObjectPtr obj = xmlXPathEvalExpression("/*/*[@Enable=\"YES\"]/Child", ctx); /* check for errors */
xmlXPathNodeSetIsEmpty(obj->nodesetval);          /* check for errors */
int n_nodes = obj->nodesetval->nodeNr;            /* this is correctly identified as 5 */
xmlNodePtr node = obj->nodesetval->nodeTab[0];    /* list of parsed Child nodes */
xmlAttrPtr attr = NULL;
for (int i = 0; i < n_nodes; i++) {
  attr = xmlGetProp(node, "attr1");               /* correctly gets the attribute value */
  /* process attribute info */
  xmlFree(attr);
  node = node->next;
}
xmlXPathFreeObject(obj);     /* cleanup code */
xmlFreeDoc(doc);
xmlCleanupParser();

现在,上述逻辑中的“n_nodes”变量正确识别了所有“MediumNode”节点中“Child”节点的数量(实际XML文件有几个MediumNode节点) .但是当 for 循环开始时,它在仅从第一个“MediumNode”节点解析出“Child”节点后崩溃。在上述情况下,它将在第一个“MediumNode”的 3 个节点后崩溃。我写的逻辑有什么错误吗?请随意指出。我已经在这里待了 2 天了。 哦,使用的 xpath 在命令行上使用 xmlstarlet 二进制文件进行验证:

xmlstarlet sel -t -c "/*/*[@Enable=\"YES\"]/Child" /path/to/xml

这会正确输出所有五个“子”节点。 我在自定义嵌入式 Linux 3.2.0、libc 2.13、libxml2 2.8.0

上执行此操作

谢谢。

对您的代码稍作改动即可运行。

xmlDocPtr doc = xmlParseFile("/path/to/xml");     /* check for errors */
xmlXPathContextPtr ctx = xmlXPathNewContext(doc); /* check for errors */
xmlXPathObjPtr obj = xmlXPathEvalExpression("/*/*[@Enable=\"YES\"]/Child", ctx); /* check for errors */
xmlXPathNodeSetIsEmpty(obj->nodesetval);          /* check for errors */
int n_nodes = obj->nodesetval->nodeNr;            /* this is correctly identified as 5 */
xmlNodePtr node;                                  
xmlAttrPtr attr = NULL;
for (int i = 0; i < n_nodes; i++) {
  node = obj->nodesetval->nodeTab[i];             /* gets the ith child node 
  attr = xmlGetProp(node, "attr1");               /* correctly gets the attribute value for ith node*/
  /* process attribute info */
  printf("found attr1=%s\n", attr);
  xmlFree(attr);
//  node = node->next;
}
xmlXPathFreePbject(obj);     /* cleanup code */
xmlFreeDoc(doc);
xmlCleanupParser();

上面代码的调试输出是这样的:

found attr1=1
found attr1=2
found attr1=3
found attr1=4
found attr1=5

对于您的代码,问题出在 for 循环中 - 而不是您的 xpath。如果您在循环中打印属性值,您将看到它在每个正确的属性后打印 (null)。你代码的调试输出是这样的:

found attr1=1
found attr1=(null)
found attr1=2
found attr1=(null)
found attr1=3