XSL Sort for XML

时间:2011-06-30 15:09:48

标签: java xml xslt

请查找输入和输出xml文件。 XML在“代码”节点上排序(按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</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>

2 个答案:

答案 0 :(得分:1)

我可以详细描述<xsl:sort>,但是w3schools可以比我做得更好:

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

您可以定义一个模板,通过稍微修改身份模板,按照其值对任何节点进行排序:

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

根据您的评论,我相信您需要这样的内容:

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

答案 1 :(得分:0)

由于您尚未说明数据应如何排序,因此很难给出确切的答案。

xsl:sort元素可用于对列表进行排序,与下面不典型示例中的for-each选项一样。

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

请注意,CodeCodeValue数字排序,BonusBonusOfferNumber数字排序,Supplier按字母顺序排列SupplierName