我有一个这样的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标记插入到其中,其中索引是当前最高的索引,加上一个。我是这样做的(为了简洁起见删除了健全性检查):
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,你是我唯一的希望!