XPath sorting results in the same order as multiple selection options

I have an XML document as follows:

<objects>
  <object uid="0" />
  <object uid="1" />
  <object uid="2" />
</objects>

I can select multiple items using the following query:

doc.xpath("//object[@uid=2 or @uid=0 or @uid=1]")

But this returns the elements in the same order in which they are declared in the XML document (uid = 0, uid = 1, uid = 2), and I want the results to be in the same order as me when I execute the XPath query ( uid = 2, uid = 0, uid = 1).

I'm not sure if this is only possible with XPath, and looked at XSLT sorting, but I did not find an example explaining how I could achieve this.

I work in Ruby with the Nokogiri library.

+1
source share
5 answers

XSLT Example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="pSequence" select="'2 1'"/>
    <xsl:template match="objects">
        <xsl:for-each select="object[contains(concat(' ',$pSequence,' '),
                                              concat(' ',@uid,' '))]">
            <xsl:sort select="substring-before(concat(' ',$pSequence,' '),
                                               concat(' ',@uid,' '))"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Conclusion:

<object uid="2" /><object uid="1" />
0

XPath 1.0 .

XPath 2.0 sequence :

//object[@uid=2], //object[@uid=1]

, object @uid=2 object @uid=1

anXPath 2.0, - XSLT .

XSLT:

<xsl:copy-of select="//object[@uid=2]"/>

<xsl:copy-of select="//object[@uid=1]"/>

:

<object uid="2" /><object uid="1" />
+4

, XPath 1.0. W3C : XPath - . Expr. , :

* node-set (an unordered collection of nodes without duplicates)
* boolean (true or false)
* number (a floating-point number)
* string (a sequence of UCS characters)

, XPath. ( , , , , (, ).

XSLT <xsl:sort>, () . XSLT FAQ , .

+1

, xpath, XSLT, xsl: sort:

<xsl:for-each select="//object[@uid=1 or @uid=2]">
  <xsl:sort: select="@uid" data-type="number" />
  {insert new logic here}
</xsl:for-each>

: http://www.w3schools.com/xsl/el_sort.asp

0

:

require 'nokogiri'

xml = '<objects><object uid="0" /><object uid="1" /><object uid="2" /></objects>'

doc = Nokogiri::XML(xml)
objects_by_uid = doc.search('//object[@uid="2" or @uid="1"]').sort_by { |n| n['uid'].to_i }.reverse
puts objects_by_uid

:

<object uid="2"/>
<object uid="1"/>

:

objects_by_uid = doc.search('//object[@uid="2" or @uid="1"]').sort { |a,b| b['uid'].to_i <=> a['uid'].to_i }

sort_by reverse.

XPath , , , , , Ruby, Perl Python. , , XML uid, . XPath , XPath object .

0

All Articles