2

我的任务是将 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
4

1 回答 1

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
于 2013-07-23T07:53:00.873 回答