gpt4 book ai didi

xml - 获取没有特定祖先xml xpath的节点

转载 作者:行者123 更新时间:2023-12-03 17:06:32 26 4
gpt4 key购买 nike

我在相当复杂的xpath中苦苦挣扎了几天,我无法制定它。
我有一个来自c ++的语法树,例如语言解析器,我想进行xpath查询,该查询选择所有不在函数名称中的名称。

具体来说,我有这样的xml文件

(整个xml文档位于问题的最后,相当大,我在此处粘贴了文档结构的简单概述)
有四种节点类型
a-此元素包含一个节点
b-包含节点的信息(例如“ CALL_EXPRESSION”)
c-包含实际文本(例如“ printf”,变量名...)
d-包含当前节点的后代(a元素)

CALL_EXPRESSION  DOT_EXPRESSION    NAME_EXPRESSION      NAME    NAME_EXPRESSION      NAME  PARAMS    NAME_EXPRESSION      NAMECALL_EXPRESSION  NAME_EXPRESSION    NAME  PARAMS    NAME_EXPRESSION      NAMEASSIGNMENT_EXPRESSION  NAME_EXPRESSION    NAME  NAME_EXPRESSION    NAME

I would like to formulate Xpath query, that would select all NAMEs that are not descendats of CALL_EXPRESSION/*[1]. (This means i would like to select all variables and not the function names).

To select all the function names I can use Xpath like this

//a[b="CALL_EXPRESSION"]/d/a[1]

no problem here. Now, if I would like to select all nodes that are not descendats of this nodes. I would use not(ancestor::X).

But here goes the problem, if I formulate the Xpath expression like this:

//*[b="NAME"][not(ancestor::a[b="CALL_EXPRESSION"]/d/a[1])]

it selects only nodes, that don't have a that has child b="CALL_EXPRESSION" at all. In our example, it selects only NAME from the ASSIGNMENT_EXPRESSION subtree.

I suspected, that the problem is, that ancestor:: takes only the first element (in our case a[b="CALL_EXPRESSION"]) and restricts according to its predicate and further / are discarded. So i modified the xpath query like this:

//*[b="NAME"][not(ancestor::a[../../b="CALL_EXPRESSION" and position()=1])]

This seems to work only on the simpler CALL_EXPRESSION (without the DOT_EXPRESSION). I suspected, that the path in [] might be relative only to current node, not to the potential ancestors. But when I used the query

//*[b="NAME"][not(ancestor::a[b="CALL_EXPRESSION"])]

it worked as one would assume (all NAMEs what don't have ancestor CALL_EXPRESSION were selected).

Is there any way to formulate the query I need? And why don't the queries work?

Thanks in advance :)

The XML

<a>
<b>CALL_EXPRESSION</b>
<c>object.method(a)</c>
<d>
<a>
<b>DOT_EXPRESSION</b>
<c>object.method</c>
<d>
<a>
<b>NAME_EXPRESSION</b>
<c>object</c>
<d>
<a>
<b>NAME</b>
<c>object</c>
<d>
</d>
</a>
</d>
</a>
<a>
<b>NAME_EXPRESSION</b>
<c>method</c>
<d>
<a>
<b>NAME</b>
<c>method</c>
<d>
</d>
</a>
</d>
</a>
</d>
</a>
<a>
<b>PARAMS</b>
<c>(a)</c>
<d>
<a>
<b>NAME_EXPRESSION</b>
<c>a</c>
<d>
<a>
<b>NAME</b>
<c>a</c>
<d>
</d>
</a>
</d>
</a>
</d>
</a>
</d>
</a>

<a>
<b>CALL_EXPRESSION</b>
<c>puts(b)</c>
<d>
<a>
<b>NAME_EXPRESSION</b>
<c>puts</c>
<d>
<a>
<b>NAME</b>
<c>puts</c>
<d>
</d>
</a>
</d>
</a>
<a>
<b>PARAMS</b>
<c>(b)</c>
<d>
<a>
<b>NAME_EXPRESSION</b>
<c>b</c>
<d>
<a>
<b>NAME</b>
<c>b</c>
<d>
</d>
</a>
</d>
</a>
</d>
</a>
</d>
</a>

<a>
<b>ASSIGNMENT_EXPRESSION</b>
<c>c=d;</c>
<d>
<a>
<b>NAME_EXPRESSION</b>
<c>c</c>
<d>
<a>
<b>NAME</b>
<c>c</c>
<d>
</d>
</a>
</d>
</a>
<a>
<b>NAME_EXPRESSION</b>
<c>d</c>
<d>
<a>
<b>NAME</b>
<c>d</c>
<d>
</d>
</a>
</d>
</a>
</d>
</a>

最佳答案

您没有说这是XPath 1.0还是2.0。在XPath 2.0中,可以使用except运算符:例如

//* except //x//*


选择所有没有x的元素作为祖先。

还可以使用等效项在XPath 1.0中模拟except运算符

E1 except E2 ==> E1[count(.|E2)!=count(E2)]


(但要注意评估E2的环境)。

关于xml - 获取没有特定祖先xml xpath的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6012439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com