开发者

XSL Sort for XML

开发者 https://www.devze.com 2023-03-16 23:31 出处:网络
Please find the input and output xml files. The XML is sorted on \"Code\" node ( sorted on CodeValue).

Please find the input and output xml files. The XML is sorted on "Code" node ( sorted on CodeValue).

INPUT XML

<?xml version="1.0" encoding="UTF-8"?>
<Service>
    <Account>
        <AccountNumber>AB1234</AccountNumber>       
        <Code>
            <CodeType>ABC</CodeType>
            <CodeValue>3456</CodeValue>
        </Code>
        <Code>
            <CodeType>ZCR</CodeType>
            <CodeValue>1234</CodeValue>
        </Code>
        <Bonus>
            <BonusDescription>INCR</BonusDescription>
            <BonusOfferNumber>1004</BonusOfferNumber>
        </Bonus>
        <Bonus>
            <BonusDescription>BNP</BonusDescription>
            <BonusOfferNumber>1326</BonusOfferNumber>
        </Bonus>
        <AccountOption>
            <AccountOptionNumber>1</AccountOptionNumber>
            <Supplier>
                <SupplierName>HSBC</SupplierName>
                <SupplierDetails>UK</SupplierDetails>
            </Supplier>
            <Supplier>
                <SupplierName>BARCLAYS</SupplierName>
                <SupplierDetails>US</SupplierDetails>
            </Supplier>
        </AccountOption>
    </Account>    
    <Account>
        <AccountNumber>AC7658</AccountNumber>       
        <Code>
            <CodeType>HGV</CodeType>
            <CodeValue>6780</CodeValue>
        </Code>
        <Code>
            <CodeType>MNR</CodeType>
            <CodeValue>67</CodeValue>
        </Code>
        <Bonus>
            <BonusDescription>BNP</BonusDescription>
            <BonusOfferNumber>5678</BonusOfferNumber>
        </Bonus>
        <Bonus>
            <BonusDescription>INCR</BonusDescription>
            <BonusOfferNumber>7804</BonusOfferNumber>
        </Bonus>
        <AccountOption>
            <AccountOptionNumber>9</AccountOptionNumber>
            <Supplier>
                <SupplierName>NAT</SupplierName>
                <SupplierDetails>US</SupplierDetails>
            </Supplier>
            <Supplier>
                <SupplierName>LKM</SupplierName>
                <SupplierDetails>GB</SupplierDetails>
            </Supplier>
        </AccountOption>
    </Account>    
</Service>

OUTPUT XML:

<?xml version="1.0" encoding="UTF-8"?>
<Service>
    <Account>
        <AccountNumber>AB1234</AccountNumber>       
        <Code>
            <CodeType>ZCR</CodeType>
            <CodeValue>1234</CodeValue>
        </Code>
        <Code>
            <CodeType>ABC</CodeType>
            <CodeValue>3456</CodeValue>
        </Code>
        <Bonus>
            <BonusDescription>INCR</BonusDescription>
            <BonusOfferNumber>1004</BonusOfferNumber>
        </Bonus>
        <Bonus>
            <BonusDescription>BNP</BonusDescription>
            <BonusOfferNumber>1326</BonusOfferNumber>
        </Bonus>
        <AccountOption>
            <AccountOptionNumber>1</AccountOptionNumber>
            <Supplier>
                <SupplierName>HSBC</SupplierName>
                <SupplierDetails>UK</SupplierDetails>
            </Supplier>
            <Supplier>
                <SupplierName>BARCLAYS</SupplierName>
                <SupplierDetails>US</SupplierDetails>
            </Supplier>
        </AccountOption>
    </Account>    
    <Account>
        <AccountNumber>AC7658</AccountNumber>       
        <Code>
            <CodeType>MNR</CodeType>
            <CodeValue>67</CodeValue>
        </Code>
        <Code>
            <CodeType>HGV</CodeType>
            <CodeValue>6780</CodeValue>
        </Code>
        <Bonus>
            <BonusDescription>BNP</BonusDe开发者_开发技巧scription>
            <BonusOfferNumber>5678</BonusOfferNumber>
        </Bonus>
        <Bonus>
            <BonusDescription>INCR</BonusDescription>
            <BonusOfferNumber>7804</BonusOfferNumber>
        </Bonus>
        <AccountOption>
            <AccountOptionNumber>9</AccountOptionNumber>
            <Supplier>
                <SupplierName>NAT</SupplierName>
                <SupplierDetails>US</SupplierDetails>
            </Supplier>
            <Supplier>
                <SupplierName>LKM</SupplierName>
                <SupplierDetails>GB</SupplierDetails>
            </Supplier>
        </AccountOption>
    </Account>    
</Service>


I could describe <xsl:sort> in detail, but w3schools can do so better than I:

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

You can define a template to sort any node by it's value with a slight modification to the identity template:

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

Based on your comments, I believe you need something like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="sort" />

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:choose>
        <xsl:when test="name() = $sort">
          <xsl:apply-templates select="@* | node()">
            <xsl:sort />
          </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="@* | node()" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>


As you haven't stated how the data should be sorted it is hard to give an exact answer.

The xsl:sort element can be used to sort listings, as with the for-each selects in the inelegant example below.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
  <xsl:for-each select="//Account">
      <xsl:for-each select="Code">
        <xsl:sort select="CodeValue" data-type="number"/>
        <xsl:copy-of select="."></xsl:copy-of>    
      </xsl:for-each>
      <xsl:for-each select="Bonus">
        <xsl:sort select="BonusOfferNumber" data-type="number"/>
        <xsl:copy-of select="."></xsl:copy-of>    
      </xsl:for-each>
      <xsl:for-each select="AccountOption">
        <xsl:sort select="AccountOptionNumber" data-type="number"/>
        <xsl:copy-of select="AccountOptionNumber"/>
        <xsl:for-each select="Supplier">
            <xsl:sort select="SupplierName"/>
            <xsl:copy-of select="."></xsl:copy-of>    
        </xsl:for-each>
      </xsl:for-each>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

Note that Code is sorted numerically by CodeValue, Bonus numerically by BonusOfferNumber and Supplier alphabetically by SupplierName.

0

精彩评论

暂无评论...
验证码 换一张
取 消