2013-07-23 42 views
2

我的任务是将xml数据转换为csv(逗号分隔符数据)。 我有输出数据排序问题。 请看下面的例子。XSLT排序输出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

貌似排序应该由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