Select elements in reverse order
I have the XML shown below I would be very grateful if someone could show me how to select the Parcel element first, then the DeliveryAddress element and then the Consignment element, these elements are repeated in the XML document as shown.
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="mr23030b1.xsl"?>
<MR23030B>
<Header RECORD_TYPE="HD" METER_NO="10800" FILE_DATE="23/06/2011">
<SenderAddress RECORD_TYPE="AS" COUNTRY_CODE="GB" BRANCH_PREFIX="" BRANCH_CODE=""/>
<Consignment RECORD_TYPE="CO" ACNT_NO="044375530" COLL_PT="0001"/>
<DeliveryAddress RECORD_TYPE="AD" COUNTRY_CODE="GB" BRANCH_CODE="7255"/>
<Parcel RECORD_TYPE="PA" MANIFEST_NO="0000000000" PARCEL_NO="JD0002210800004322"/>
<Consignment RECORD_TYPE="CO" ACNT_NO="044375531" CONT_NO="9360964" />
<DeliveryAddress RECORD_TYPE="AD" COUNTRY_CODE="GB" BRANCH_CODE="7256"/>
<Parcel RECORD_TYPE="PA" MANIFEST_NO="0000000000" PARCEL_NO="JD0002210800004323"/>
<Consignment RECORD_TYPE="CO" ACNT_NO="044375532" CONT_NO="9360964" />
<DeliveryAddress RECORD_TYPE="AD" COUNTRY_CODE="GB" BRANCH_CODE="7257"/>
<Parcel RECORD_TYPE="PA" MANIFEST_NO="0000000000" PARCEL_NO="JD0002210800004324"/>
<TrailerRecord RECORD_TYPE="TR" NO_RECORDS="00000425"/>
</MR23030B>
XSL style sheet I am using:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="MR23030B">
xsl:apply-templates/>
</xsl:template>
<xsl:output method='text'/>
<xsl:variable name='newline'>
<xsl:text> </xsl:text>
</xsl:variable>
<xsl:template match="MR23030B">
<xsl:apply-templates select="/*/Parcel,/*/DeliveryAddress,/*/Consignment"/>
</xsl:template>
<xsl:template match="Parcel">
<xsl:value-of select="@PARCEL_NO"/>
<xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="DeliveryAddress">
<xsl:value-of select="@BRANCH_CODE"/>
<xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="Consignment">
<xsl:value-of select="@ACNT_NO"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="$newline"/>
</xsl:template>
I tried the above xsl stylesheet but I am still getting the data coming out in the wrong order i.e. its reading the Consignment element first, then the DeliveryAddress and finally the Parcel. i.e 044375530 7255 JD0002210800004322 044375531 7256 JD0002210800004323 044375532 7257 JD0002210800004324
As yo开发者_开发知识库u know I want the Parcel element first then the Delivery address and the the Consignment element.
I would be very grateful if someone could tell me whats wrong with the style sheet.
In XPath 2.0:
for $cnt in count($yourExpression),
$i in 0 to $cnt -1
return
$yourExpression[$cnt - $i]
WIth XSLT 1.0 (XPath 1.0)
<xsl:for-each select="$yourExpression">
<xsl:sort select="position()"
data-type="number" order="descending"/>
<!--Process an individual node here -->
</xsl:for-each>
XPath 1.0 technically returns node-sets which have no defined order; but because of the widespread association with XSLT, most XPath APIs can be relied on to deliver node-sets in document order, even though the API documentation often forgets to mention the fact.
To deliver a sequence of nodes in anything other than document order, you need XPath 2.0. This allows you an expression like
/*/Parcel, /*/DeliveryAddress, /*/Consignment
which returns nodes in any order you want. (Beware though of a mistake which I made before editing this answer: any expression that contains a "/" returns results in document order.)
It all depends on the language. But the general algorithm is to just load all of the "MR23030B" elements into a list and just traverse that list backwards.
So I use the java.xml.xpath class frequently. And to load all of the nodes in I'd use an expression like this: "//MR23030B/descendant::*"
Then you just use a for loop to traverse the list of nodes backwards and you're all set. It varies based on the language you are using though.
精彩评论