c - libxml2 中奇怪的 XPath 行为

标签 c xml xpath libxml2

我有一个看起来像这样的 XML 树(我已经更改了标签名称,但如果你真的很聪明,你可能会明白我实际上在做什么。)

<ListOfThings>
   <Thing foo:action="add">
      <Bar>doStuff --slowly</Bar>
      <Index>1</Index>
   </Thing>
   <Thing foo:action="add">
      <Bar>ping yourMother.net</Bar>
      <Index>2</Index>
   </Thing>
</ListOfThings>

使用 libxml2,我想以编程方式将新的 Thing 标记插入到 ListOfThings 中,索引是当前最高索引加一。我这样做(为简洁起见删除了完整性检查):

xpath = "//urn:myformat[@foo='bar']/"
        "urn:mysection[@name='baz']/"
        "urn:ListOfThings/urn:Thing/urn:Index";

xpathObj = xmlXPathEvalExpression(xpath, xpathCtx);
nodes = xpathObj->nodesetval;

/* Find last value and snarf the value of the tag */
highest = atoi(nodes->nodeTab[nodes->nodeNr - 1]->children->content);
snprintf(order, sizeof(order), "%d", highest + 1); /* highest index plus one */

/* now move up two levels.. */
cmdRoot = nodes->nodeTab[nodes->nodeNr - 1];
ASSERT(cmdRoot->parent && cmdRoot->parent->parent);
cmdRoot = cmdRoot->parent->parent;

/* build the child tag */
newTag = xmlNewNode(NULL, "Thing");
xmlSetProp(newTag, "foo:action", "add");

/* set new node values */
xmlNewTextChild(newTag, NULL, "Bar", command);
xmlNewChild(newTag, NULL, "Index", order);

/* append this to cmdRoot */
xmlAddChild(cmdRoot, newTag);

但是如果我调用这个函数两次(添加两个事物),XPath 表达式不会捕捉到我创建的新条目。有没有我需要调用的函数来刺激 XPath 并让它确保它真的再次查看整个 xmlDocPtr?它显然确实被添加到文档中,因为当我保存它时,我得到了我添加的新标签。

为了清楚起见,输出如下所示:

<ListOfThings>
   <Thing foo:action="add">
      <Bar>doStuff --slowly</Bar>
      <Index>1</Index>
   </Thing>
   <Thing foo:action="add">
      <Bar>ping yourMother.net</Bar>
      <Index>2</Index>
   </Thing>
   <Thing foo:action="add">
      <Bar>newCommand1</Bar>
      <Index>3</Index>
   </Thing>
   <Thing foo:action="add">
      <Bar>newCommand2</Bar>
      <Index>3</Index> <!-- this is WRONG! -->
   </Thing>
</ListOfThings>

我使用调试器检查调用 xmlXPathEvalExpression 后发生了什么,我看到 nodes->nodeNr 每次都是相同的。

帮帮我,lazyweb,你是我唯一的希望!

最佳答案

根据您的 XPath,它看起来只是命名空间文档的一个片段(当时使用默认命名空间)。我打赌您事先调用过使用 xmlXPathRegisterNs 将“urn”注册为 namespace 的前缀。当您添加新节点时,您并不是在命名空间中创建它们,因此 XPath 正确地只选择命名空间的“索引”元素。

关于c - libxml2 中奇怪的 XPath 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2459428/

相关文章:

javascript - 如何使用JQuery正确获取跨域的xml

html - 子 XPath 轴和后代 XPath 轴有什么区别?

WPF 绑定(bind)到元素属性的 XPath 可访问值

python - XPath:通过*纯*文本查找 HTML 元素

c - 嵌入式编程

c - 使用 qsort 对多个数组进行排序

c++ - 从源代码项目中提取所有功能的工具

c - 将整数从父级传递给子级的错误输出

xml - XPath for xml in YQL?

java - android中的自定义复选框类