要仅在某个子树内评估XPath表达式,libxml2函数xmlXPathNodeEval()
似乎是要走的路。在给定的上下文中评估XPath表达式的documentation specifies'。但这究竟意味着什么?
请考虑以下小例子:
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xmlstring.h>
#include <stdio.h>
int main(int argc, char **argv)
{
const char inp[] =
"<root>\n"
" <sub>\n"
" <e>0</e>\n"
" <Foo>\n"
" <e>1</e><e>2</e><e>3</e>\n"
" <FooSub><e>3a</e></FooSub>\n"
" </Foo>\n"
" <Bar>\n"
" <e>4</e><e>5</e><e>6</e>\n"
" </Bar>\n"
" </sub>\n"
" <e>7</e>\n"
"</root>\n";
xmlDoc *doc = xmlParseMemory(inp, sizeof(inp)-1);
xmlXPathContext *ctx = xmlXPathNewContext(doc);
xmlXPathObject *p = xmlXPathEval(BAD_CAST "//Foo[1]", ctx);
xmlNode *new_root = *p->nodesetval->nodeTab;
printf("New root: %s\n", BAD_CAST new_root->name);
xmlXPathObject *q = xmlXPathNodeEval(new_root, BAD_CAST argv[1], ctx);
for (int i = 0; i<q->nodesetval->nodeNr; ++i) {
const xmlChar *cnt = xmlNodeGetContent(q->nodesetval->nodeTab[i]);
printf("%s ", BAD_CAST cnt);
xmlFree((xmlChar*)cnt);
}
puts("");
xmlXPathFreeObject(q);
xmlXPathFreeObject(p);
xmlXPathFreeContext(ctx);
xmlFreeDoc(doc);
return 0;
}
编译通过(在我的例子中使用libxml的2.9.1版本):
$ gcc -g -std=c99 -Wall -I/usr/include/libxml2 -lxml2 relative.c
致电
$ ./a.out '//e'
我希望得到以下结果:
New root: Foo 1 2 3 3a
但我得到了:
New root: Foo 0 1 2 3 3a 4 5 6 7
似乎我必须使用self::node()
轴说明符(短.
)来获得我想要的结果,即:
$ ./a.out './/e'
New root: Foo
1 2 3 3a
基本上我正在解释句子&#39;在给定的上下文中评估XPath位置路径&#39;从文档中可以看出:XPath表达式在给定节点的self::node()
上下文中进行评估 - 但由于必须明确指定self::node()
,因此不是这种情况。
因此,一个相关的问题可能是:libxml2的行为及其对术语“上下文”的使用。与XPath规范一致吗?
答案 0 :(得分:2)
XPath选择输入树中的节点,以斜杠/
开头的路径从上下文节点的文档节点向下选择节点。因此,正确地发现,如果要选择相对于上下文节点的后代,则需要.//foo
。作为替代方案,您可以使用descendant::foo
。