XSLT排序输出csv数据

时间:2013-07-23 07:34:19

标签: sorting xslt

我的任务是将xml数据转换为csv(逗号分隔符数据)。 我在输出数据中排序有问题。 请看下面的例子。

请提供有关如何解决此问题的任何建议。 提前谢谢!

输入XML数据

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <ItemInfo>
    <ItemNmb>Item1</ItemNmb>
    <ItemText>Item 111</ItemText>
    <ItemDetails>
      <ItemDetailInfo>
        <id>111</id>
        <Text>Text 111</Text>        
      </ItemDetailInfo>
      <ItemDetailInfo>
        <id>555</id>
        <Text>Text 555</Text>        
      </ItemDetailInfo>     
    </ItemDetails>    
  </ItemInfo>
  <ItemInfo>
    <ItemNmb>Item2</ItemNmb>
    <ItemText>Item 222</ItemText>
    <ItemDetails>
      <ItemDetailInfo>
        <id>555</id>
        <Text>Text 555</Text>        
      </ItemDetailInfo>
      <ItemDetailInfo>
        <id>333</id>
        <Text>Text 333</Text>
      </ItemDetailInfo>
      <ItemDetailInfo>
        <id>222</id>
        <Text>Text 222</Text>
      </ItemDetailInfo>
    </ItemDetails>
  </ItemInfo>
  <ItemInfo>
    <ItemNmb>Item3</ItemNmb>
    <ItemText>Item 333</ItemText>
    <ItemDetails>
      <ItemDetailInfo>
        <id>999</id>
        <Text>Text 999</Text>
      </ItemDetailInfo>     
    </ItemDetails>
  </ItemInfo>  
</Root>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <xsl:output method="text" encoding="UTF-8" indent="yes"/>


  <xsl:param name="delim" select="';'"/>
  <xsl:param name="break" select="'&#xA;'"/>

  <xsl:template match="/">

  <xsl:for-each select="/Root/ItemInfo">
      <xsl:call-template name="itemtemp">
          <xsl:with-param name="item" select="ItemNmb"/>
          <xsl:with-param name="text" select="ItemText"/>         
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="itemtemp">
    <xsl:param name="item"/>
    <xsl:param name="text"/>

    <xsl:for-each select="ItemDetails/ItemDetailInfo">
      <xsl:sort select="id" data-type="text" order="ascending"/>
      <xsl:call-template name="copmitemtemp">
        <xsl:with-param name="item" select="$item"/>
        <xsl:with-param name="text" select="$text"/>
        <xsl:with-param name="idsub" select="id"/>
        <xsl:with-param name="textsub" select="Text"/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="copmitemtemp">
    <xsl:param name="item"/>
    <xsl:param name="text"/>
    <xsl:param name="idsub"/>
    <xsl:param name="textsub"/>


    <xsl:value-of select="$idsub" disable-output-escaping="yes"/><xsl:value-of select="$delim"/>
    <xsl:value-of select="$textsub" disable-output-escaping="yes"/><xsl:value-of select="$delim"/>
    <xsl:value-of select="$item" disable-output-escaping="yes"/><xsl:value-of select="$delim"/>
    <xsl:value-of select="$text" disable-output-escaping="yes"/><xsl:value-of select="$break"/>

  </xsl:template>

</xsl:stylesheet>

输出数据

111;Text 111;Item1;Item 111
555;Text 555;Item1;Item 111
222;Text 222;Item2;Item 222
333;Text 333;Item2;Item 222
555;Text 555;Item2;Item 222
999;Text 999;Item3;Item 333

预期结果(按(ID)排序)

111;Text 111;Item1;Item 111
222;Text 222;Item2;Item 222
333;Text 333;Item2;Item 222
555;Text 555;Item1;Item 111
555;Text 555;Item2;Item 222
999;Text 999;Item3;Item 333

1 个答案:

答案 0 :(得分:1)

看起来排序应该由ItemInfo/ItemDetails/ItemDetailInfo/id完成,因此您需要迭代ItemDetailInfo
试试你的xslt的这个稍微改变的版本。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="text" encoding="UTF-8" indent="yes"/>


    <xsl:param name="delim" select="';'"/>
    <xsl:param name="break" select="'&#xA;'"/>

    <xsl:template match="/">

        <xsl:for-each select="/Root/ItemInfo/ItemDetails/ItemDetailInfo">
            <xsl:sort select="id" data-type="text" order="ascending"/>
            <xsl:call-template name="copmitemtemp">
                <xsl:with-param name="item" select="../../ItemNmb"/>
                <xsl:with-param name="text" select="../../ItemText"/>
                <xsl:with-param name="idsub" select="id"/>
                <xsl:with-param name="textsub" select="Text"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="copmitemtemp">
        <xsl:param name="item"/>
        <xsl:param name="text"/>
        <xsl:param name="idsub"/>
        <xsl:param name="textsub"/>


        <xsl:value-of select="$idsub" disable-output-escaping="yes"/>
        <xsl:value-of select="$delim"/>
        <xsl:value-of select="$textsub" disable-output-escaping="yes"/>
        <xsl:value-of select="$delim"/>
        <xsl:value-of select="$item" disable-output-escaping="yes"/>
        <xsl:value-of select="$delim"/>
        <xsl:value-of select="$text" disable-output-escaping="yes"/>
        <xsl:value-of select="$break"/>

    </xsl:template>

</xsl:stylesheet>

这将生成以下输出

111;Text 111;Item1;Item 111
222;Text 222;Item2;Item 222
333;Text 333;Item2;Item 222
555;Text 555;Item1;Item 111
555;Text 555;Item2;Item 222
999;Text 999;Item3;Item 333