私はこのような 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 にプログラムで挿入したいと考えています。Index は現在の最高のインデックスに 1 を加えたものです。私は次のようにします(簡潔にするためにサニティチェックを削除しました):
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);
しかし、この関数を 2 回 (2 つのモノを追加するために) 呼び出すと、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、あなたが私の唯一の希望です!