按相反顺序选择元素

时间:2011-09-16 19:41:09

标签: xml xslt xpath

我有下面显示的XML如果有人能告诉我如何首先选择Parcel元素,然后是DeliveryAddress元素然后是Consignment元素,我将非常感激,这些元素在XML文档中重复,如图所示。

  <?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样式表:

<?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>&#10;</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>

我尝试了上面的xsl样式表,但我仍然以错误的顺序输出数据,即首先读取Consignment元素,然后是DeliveryAddress,最后是包裹。即044375530 7255 JD0002210800004322 044375531 7256 JD0002210800004323 044375532 7257 JD0002210800004324

如您所知,我首先需要Parcel元素,然后是Delivery地址和Consignment元素。

如果有人能告诉我样式表的错误,我将非常感激。

3 个答案:

答案 0 :(得分:3)

在XPath 2.0中

for $cnt in count($yourExpression),
    $i in 0 to $cnt -1
  return
    $yourExpression[$cnt - $i]

与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>

答案 1 :(得分:0)

XPath 1.0技术上返回没有定义顺序的节点集;但是由于与XSLT的广泛关联,大多数XPath API都可以依赖于按文档顺序提供节点集,即使API文档经常忘记提及这一事实。

要以除文档顺序之外的任何其他方式提供节点序列,您需要XPath 2.0。这允许你使用像

这样的表达式
/*/Parcel, /*/DeliveryAddress, /*/Consignment

以任何您想要的顺序返回节点。 (请注意,在编辑此答案之前我犯了一个错误:任何包含“/”的表达式都会按文档顺序返回结果。)

答案 2 :(得分:0)

这完全取决于语言。但是通用算法只是将所有“MR23030B”元素加载到列表中,然后向后遍历该列表。

所以我经常使用java.xml.xpath类。并加载我的所有节点使用这样的表达式:“// MR23030B / descendant :: *”

然后你只需使用for循环向后遍历节点列表就可以了。它会根据您使用的语言而有所不同。