XPath 查询未使用 VTDNav/AutoPilot 按文档顺序将结果作为节点序列返回

Posted

技术标签:

【中文标题】XPath 查询未使用 VTDNav/AutoPilot 按文档顺序将结果作为节点序列返回【英文标题】:XPath query not returning result as sequence of nodes in document order using VTDNav/AutoPilot 【发布时间】:2020-08-28 02:17:39 【问题描述】:

我有以下 xml 结构。

<body>
    <level recover="true">1</level>
    <span>
        <level recover="true">1.1</level>
        <span>
            <level recover="true">1.1.1</level>
        <span>
    <span>
    <level recover="true">2</level>
    <level recover="true">3</level>
<body>

xpath query: //*[@recover='true']"

结果:1​​、2、3、1.1、1.1.1

似乎 xpath 处理器按深度构建结果深度。首先处理第一个深度级别,从那里检索 1、2 和 3,然后进入第二个深度级别并检索 1.1,然后到第三级并检索 1.1.1.

我需要按以下顺序检索结果: 1、1.1、1.1.1、2、3

更新 作为 XML 处理器,我使用的是https://vtd-xml.sourceforge.io/userGuide/4.html

VTDGen vtdGen = new VTDGen();
vtdGen.setDoc(xmlByteContent);
VTDNav vtdNav = vtdGen.getNav();

AutoPilot autoPilot = new AutoPilot(vtdNav);
autoPilot.selectXPath("//*[@recover='true']");
<dependency>
    <groupId>com.ximpleware</groupId>
    <artifactId>vtd-xml</artifactId>
    <version>2.13</version>
</dependency>

提前谢谢你。

【问题讨论】:

【参考方案1】:

有趣。在 XPath 2.0 中,该表达式被定义为按文档顺序返回一系列节点,这就是您要查找的顺序。在 XPath 1.0 中没有定义顺序,但我认为所有常用的 XPath 1.0 处理器都以文档顺序返回结果,因为这是 XSLT 需要的,并且大多数 XPath 1.0 处理器在设计时都考虑了 XSLT。看来你发现了一个例外。

知道您使用的是什么 XPath 处理器会很有趣。您可能需要换一个。

您得到的结果符合 XPath 1.0 规范,但仍然令人惊讶。

稍后

除了名声,我不知道 VTD。据我了解,他们将其设计为以性能为第一目标,而不是其他所有目标。因此,如果规范允许他们以任何顺序返回节点,我并不感到惊讶他们会利用这一点。您必须查看 VTD 文档以查看是否有任何方法可以强制结果中的文档顺序。或者进行实验:看看如果在表达式中添加 `|//*[@recover='true']' 会发生什么(它们可能会按文档顺序排序以有效地实现联合操作)。

进一步更新

AutoPilot.iterate() 方法声称按文档顺序返回选定的节点。

【讨论】:

感谢@Michael 的回答。如果你想看看,我用其他信息丰富了这个问题。

以上是关于XPath 查询未使用 VTDNav/AutoPilot 按文档顺序将结果作为节点序列返回的主要内容,如果未能解决你的问题,请参考以下文章

XML编程总结——使用XPath对象查询xml文档

使用 Nokogiri xpath 解析时未插入 Ruby 环境变量

使用 C# 在 Xpath 中查询元素

使用 XPath 查询从 XML 中获取值

在 Java 中使用 XPath 查询 HTML 页面

使用XPath查询读取XML标签