我在非常复杂的 xpath 上苦苦挣扎了几天,但我无法制定它。我有一个来自 c++ 的语法树,比如语言解析器,我想要一个 xpath 查询,它选择所有不在函数名中的名称。
具体来说,我有这样的xml文档
(整个xml文档在问题的最后,它很大,我在这里粘贴文档结构的简单概述)有四种节点类型
a - 此元素包含一个节点
b - 包含节点的信息(例如“CALL_EXPRESSION ")
c - 包含实际文本(例如“printf”、变量名...)
d - 包含当前节点的后代(a 元素)
CALL_EXPRESSION DOT_EXPRESSION NAME_EXPRESSION 姓名 NAME_EXPRESSION 姓名 参数 NAME_EXPRESSION 姓名 CALL_EXPRESSION NAME_EXPRESSION 姓名 参数 NAME_EXPRESSION 姓名 ASSIGNMENT_EXPRESSION NAME_EXPRESSION 姓名 NAME_EXPRESSION 姓名
我想制定 Xpath 查询,它将选择所有不是 CALL_EXPRESSION/*[1] 后代的名称。(这意味着我想选择所有变量而不是函数名称)。
要选择所有函数名称,我可以像这样使用 Xpath
//a[b="CALL_EXPRESSION"]/d/a[1]
这里没问题。现在,如果我想选择不是该节点后代的所有节点。我会使用 not(ancestor::X)。
但是问题来了,如果我像这样制定 Xpath 表达式:
//*[b="NAME"][not(ancestor::a[b="CALL_EXPRESSION"]/d/a[1])]
它只选择根本没有子 b="CALL_EXPRESSION" 的节点。在我们的示例中,它仅从 ASSIGNMENT_EXPRESSION 子树中选择 NAME。
我怀疑问题在于,祖先:: 仅采用第一个元素(在我们的例子中为 a[b="CALL_EXPRESSION"])并根据其谓词进行限制,并进一步 / 被丢弃。所以我修改了这样的xpath查询:
//*[b="NAME"][not(ancestor::a[../../b="CALL_EXPRESSION" and position()=1])]
这似乎只适用于更简单的 CALL_EXPRESSION(没有 DOT_EXPRESSION)。我怀疑,[] 中的路径可能仅与当前节点相关,而不与潜在祖先相关。但是当我使用查询时
//*[b="NAME"][not(ancestor::a[b="CALL_EXPRESSION"])]
它按照人们的假设工作(选择了所有没有祖先 CALL_EXPRESSION 的名称)。
有什么方法可以制定我需要的查询吗?为什么查询不起作用?
提前致谢 :)
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>