【问题标题】:XSLT sort parent element based on child element attributeXSLT 根据子元素属性对父元素进行排序
【发布时间】:2016-03-02 14:49:46
【问题描述】:

虽然这个问题已经被问过multiples timesherehere 之前,并且答案似乎都适用于那个特定的问题,但我无法让它在我的情况下工作。

这个xml

 <root>
  <Orders>
    <Order type="S">
      <Ref>ABC123</Ref>
      <OrderedBy>
        <Debtor code="13456"></Debtor>
      </OrderedBy>
      <DeliveryMethod code="Truck"></DeliveryMethod>
      <OrderLine line="1">
        <Item code="ABC100400"></Item>
        <Quantity>1</Quantity>
      </OrderLine>
      <OrderLine line="2">
        <Item code="XYZ490204" type="S" searchcode="XYZ490204"></Item>
        <Quantity>2</Quantity>
      </OrderLine>
      <OrderLine line="3">
        <Item code="DEF1210847" type="S" searchcode="DEF1210847"></Item>
        <Quantity>4</Quantity>
      </OrderLine>
    </Order>
    <Order type="S">
      <Ref>ABC123</Ref>
      <OrderedBy>
        <Debtor code="BLABLA" number="802416" type="C"></Debtor>
      </OrderedBy>
      <DeliveryMethod code="Barefoot"></DeliveryMethod>
      <OrderLine line="1">
        <Item code="QQQ123456" type="S" searchcode="QQQ123456"></Item>
        <Quantity>1</Quantity>
      </OrderLine>
      <OrderLine line="2">
        <Item code="JJJ490204" type="S" searchcode="JJJ490204"></Item>
        <Quantity>3</Quantity>
      </OrderLine>
    </Order>
  </Orders>
</root>

需要转换成这个xml:

 <root>
      <Orders>
        <Order type="S">
          <Ref>ABC123</Ref>
          <OrderedBy>
            <Debtor code="13456"></Debtor>
          </OrderedBy>
          <DeliveryMethod code="Truck"></DeliveryMethod>
          <OrderLine line="1">
             <Item code="ABC100400"></Item>
            <Quantity>1</Quantity>
          </OrderLine>
          <OrderLine line="3">
            <Item code="DEF1210847"></Item>
            <Quantity>4</Quantity>
          </OrderLine>
          <OrderLine line="2">
            <Item code="XYZ490204"></Item>
            <Quantity>2</Quantity>
          </OrderLine>
        </Order>
        <Order type="S">
          <Ref>ABC123</Ref>
          <OrderedBy>
            <Debtor code="BLABLA"></Debtor>
          </OrderedBy>
          <DeliveryMethod code="Barefoot"></DeliveryMethod>
          <OrderLine line="2">
            <Item code="JJJ490204"></Item>
            <Quantity>3</Quantity>
          </OrderLine>
          <OrderLine line="1">
            <Item code="QQQ123456"></Item>
            <Quantity>1</Quantity>
          </OrderLine>
         </Order>
      </Orders>
    </root>

我正在尝试对每个&lt;Order&gt; 进行排序,根据子&lt;Item&gt;/@code 的属性值对&lt;OrderLine&gt; 元素进行排序,并去除该子元素的一些属性。 OrderLine 之外的所有其他元素都需要保持不变。请不要介意 xml 的非最佳结构,这是无法更改的。它可能会复制,对于每个结合排序,像这样,但要好得多:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

    <xsl:template match="Orders">
        <xsl:copy>
            <xsl:apply-templates select="Order/OrderLine/Item|@*">
                <xsl:sort select="@code" data-type="text"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: xml sorting xslt


    【解决方案1】:

    我要做的是为每个&lt;Order&gt; 排序&lt;OrderLine&gt; 基于子&lt;Item&gt;/@code的attributevalue的元素...

    如果要对 OrderLine 元素进行排序,则必须从其父 Order 的上下文中进行:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Order">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="*[not(self::OrderLine)]"/>
            <xsl:apply-templates select="OrderLine">
                <xsl:sort select="Item/@code" data-type="text" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    
    </xsl:stylesheet>
    

    注意:由于空字符串优先排序,您可以将模板缩短为:

    <xsl:template match="Order">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="Item/@code" data-type="text" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    

    .. 并且还剥离了那个孩子的一些属性。

    我没有在您的样式表中看到它。无论如何,只需添加另一个模板来匹配Item

    【讨论】:

      猜你喜欢
      • 2021-08-12
      • 2019-06-10
      • 2018-07-31
      • 2012-10-01
      • 1970-01-01
      • 2019-05-08
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多