1

我学习 XPath 越多,我就越需要反向引用

例如,当我在一些中间步骤中发现一些信息时,有时我需要稍后使用这些信息。这个问题实际上有一个解决方法,在谓词表达式的能力的帮助下也包含 XPathes。工作解决方案可能看起来像这样

/foo/item[@attrtocheck = ../../otheritem[@anotherattr]]

但是这种方法的问题是我只是根据某些标准评估谓词,并且不能基于此获得多个后续结果。即使有许多具有相同@anotherattr 的其他项目,我也无法收集它们。所以更好的解决方案是

/foo/item[@attrtocheck]/../../otheritem[@anotherattr=BACKREFERENCING_ATTRTOCHECK_VALUE] 

但只要我知道这是不可能的。

如果标准中没有解决方案,也许某些工具/库中有扩展?实际上我实现了自己的引擎,如果已经存在非标准语法,我会采用它。

更新:迈克尔凯评论后,更多关于我为什么错过这个功能

实际上,我正在为 AST(抽象语法树)执行 XPath 搜索。我不是第一个尝试这样做的人(网络搜索 [Xpath AST])。这种搜索揭示了树的不同部分之间非常紧密的关系。例如,当我在某个上下文中(例如在某个其他方法中)找到一些调用时,我想知道这个符号是否作为虚函数引入,如果它是然后将其输出到结果中。在这种情况下,我的第一次搜索会产生一些以前未知的符号(函数名),我想在以下子路径中使用它(搜索类声明及其关键字)。因此,反向引用将非常有帮助。

我认为如果它适用于 AST,那么在其他结构化数据中就有可能存在这种关系。

4

2 回答 2

2

在 XQuery 中,您可以使用let .. return来声明临时变量。像这样:

 /foo/item[@attrtocheck]/(let $backreference := @attrtocheck return ../../otheritem[@anotherattr=$backreference]) 

在 XPath 2 中,您可以使用 for 循环模拟 let 表达式:

 /foo/item[@attrtocheck]/(for $backreference in @attrtocheck return ../../otheritem[@anotherattr=$backreference]) 

或者您可以按预期使用 for 循环,并且不使用“反向引用”:

 for $value in /foo/item[@attrtocheck]/@attrtocheck  return otheritem[@anotherattr=$value]

在这种情况下,由于比较是存在的,您可以使用:

otheritem[@anotherattr = /foo/item/@attrtocheck]

(顺便说一句,我还编写了自己的 XPath 实现,并且我有用于变量声明的语法 ((values := /xx/a/@id)[0], /xx/b[@id = $values]) := 定义变量,并且 ()[0] 防止 $values 在返回的序列中。)

于 2012-07-28T22:09:41.400 回答
0

我接受了 BeniBela 解决方案(Dimitre Novatchev 也提到过),尽管我发现这个功能在某种程度上缺乏 XPath 1.0 缩写语法的简单性和表现力。

我还考虑实现我自己的函数来反向引用以前找到的值。它将接受负偏移以相对引用先前的步骤,并且绝对地(从表达式的开头)。所以这会以类似的方式结束

 /foo/item[@attrtocheck]/../../otheritem[@anotherattr=backref(-2)]

XPath 中没有我想的这样的函数,我不会丢失一般语法,并且在路径期间引用前面的步骤乘以时间看起来比多个 for 语句更具表现力

于 2012-07-29T07:41:18.613 回答