按照与多个选择参数相同的顺序对 XPath 结果进行排序
我有一个 XML 文档,如下所示:
<objects>
<object uid="0" />
<object uid="1" />
<object uid="2" />
</objects>
我可以使用以下查询选择多个元素:
doc.xpath("//object[@uid=2 or @uid=0 or @uid=1]")
但这会按照 XML 文档中声明的顺序返回元素 (uid=0、uid=1、uid=2),并且我希望结果的顺序与我执行 XPath 查询的顺序相同(uid=2、uid=0、uid=1)。
我不确定仅使用 XPath 是否可以实现这一点,并且已经研究过 XSLT 排序,但我还没有找到解释如何实现此目的的示例。
我正在使用 Nokogiri 库使用 Ruby 进行工作。
I have an XML document as follows:
<objects>
<object uid="0" />
<object uid="1" />
<object uid="2" />
</objects>
I can select multiple elements using the following query:
doc.xpath("//object[@uid=2 or @uid=0 or @uid=1]")
But this returns the elements in the same order they're declared in the XML document (uid=0, uid=1, uid=2) and I want the results in the same order as I perform the XPath query (uid=2, uid=0, uid=1).
I'm unsure if this is possible with XPath alone, and have looked into XSLT sorting, but I haven't found an example that explains how I could achieve this.
I'm working in Ruby with the Nokogiri library.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
XPath 1.0 中无法指定所选节点的顺序。
XPath 2.0 允许节点的序列具有任何特定顺序:
计算结果为一个序列,其中所有带有
@uid=2
的object
项目位于所有带有object
项目之前code>@uid=1如果没有可用的 XPath 2.0 引擎,仍然可以使用 XSLT 以任何所需的顺序输出节点。
在此特定情况下以下 XSLT 指令的序列:
产生所需的输出:
There is no way in XPath 1.0 to specify the order of the selected nodes.
XPath 2.0 allows a sequence of nodes with any specific order:
evaluates to a sequence in which all
object
items with@uid=2
precede allobject
items with@uid=1
If one doesn't have anXPath 2.0 engine available, it is still possible to use XSLT in order to output nodes in any desired order.
In this specific case the sequence of the following XSLT instructions:
produces the desired output:
我假设您使用的是 XPath 1.0。 W3C 规范规定:
XPath 中的主要语法结构是表达式。表达式与产生式 Expr 相匹配。计算表达式以生成一个对象,该对象具有以下四种基本类型之一:
因此我认为您不能简单地使用 XPath 进行重新排序。 (规范的其余部分定义了文档顺序和反向文档顺序,因此如果后者执行您想要的操作,您可以使用适当的轴(例如前面)来获取它。
在 XSLT 中,您可以使用< /code> 使用属性的 name()。XSLT 常见问题解答非常好,你应该在那里找到答案。
I am assuming you are using XPath 1.0. The W3C spec says:
The primary syntactic construct in XPath is the expression. An expression matches the production Expr. An expression is evaluated to yield an object, which has one of the following four basic types:
So I don't think you can re-order simply using XPath. (The rest of the spec defines document order and reverse document order, so if the latter does what you want you can get it using the appropriate axis (e.g. preceding).
In XSLT you can use
<xsl:sort>
using the name() of the attribute. The XSLT FAQ is very good and you should find an answer there.XSLT 示例:
输出:
An XSLT example:
Output:
我认为在 xpath 中没有办法做到这一点,但如果您想切换到 XSLT,您可以使用 xsl:sort 标签:
这里有更完整的信息:
http://www.w3schools.com/xsl/el_sort.asp
I don't think there is a way to do it in xpath but if you wish to switch to XSLT you can use the xsl:sort tag:
more complete info here:
http://www.w3schools.com/xsl/el_sort.asp
这就是我在 Nokogiri 中执行此操作的方法:
运行该输出:
搜索的替代方法是:
如果您不喜欢将
sort_by
与reverse
一起使用。XPath 对于定位和检索节点很有用,但通常我们想要执行的过滤在访问器中变得过于复杂,因此我让语言来完成它,无论是 Ruby、Perl 还是 Python。我放置过滤逻辑的位置基于 XML 数据集的大小以及是否有很多我想要获取的不同
uid
值。有时让 XPath 引擎完成繁重的工作是有意义的,其他时候让 XPath 抓取所有object
节点并在调用语言中进行过滤会更容易。This is how I'd do it in Nokogiri:
Running that outputs:
An alternative to the search would be:
if you don't like using
sort_by
with thereverse
.XPath is useful for locating and retrieving the nodes but often the filtering we want to do gets too convoluted in the accessor so I let the language do it, whether it's Ruby, Perl or Python. Where I put the filtering logic is based on how big the XML data set is and whether there are a lot of different
uid
values I'll want to grab. Sometimes letting the XPath engine do the heavy lifting makes sense, other times its easier to let XPath grab all theobject
nodes and filter in the calling language.