每个循环中的XSLT?

时间:2012-03-16 15:47:46

标签: xslt foreach

我必须将XML转换为CSV,但对我来说转换非常困难。

这是一个示例XML:

    <?xml version="1.0" encoding="windows-1251"?>
    <message text="Contract [number] of [sum] [currency] till [deadline]" report="someone@lost.com">
    <customer mobile="X69931232">
    <contract number="FL1-22/Ml">
    <sum>21,55</sum>
    <currency>USD</currency>
    <deadline>30.09.2011</deadline>
    </contract>
    </customer>
    <customer mobile="X79484483">
    <contract number="FL1-24">
    <sum>329,44</sum>
    <currency>EUR</currency>
    <deadline>30.12.2011</deadline>
    </contract>
    <contract number="FL1-27">
    <sum>232,91</sum>
    <currency>EUR</currency>
    <deadline>30.12.2011</deadline>
    </contract>
    </customer>
    <customer mobile="X69502060, X79484483">
    <contract number="FL1-07">
    <sum>42,17</sum>
    <currency>USD</currency>
    <deadline>30.09.2011</deadline>
    </contract>
    </customer>
    <customer mobile="X69931232, X79484483">
    <contract number="FL2-01/M2">
    <sum>40,84</sum>
    <currency>EUR</currency>
    <deadline>30.09.2011</deadline>
    </contract>
    <contract number="FL1-18">
    <sum>198,45</sum>
    <currency>EUR</currency>
    <deadline>30.11.2011</deadline>
    </contract>
    </customer>
    </message>

示例CSV应如下所示:

X69931232,Contract FL1-22/Ml sum of 21,55 USD till 30.09.2011
X79484483,Contract FL1-24 sum of  329,44 EUR till 30.12.2011; FL1-27 sum of  232,91 EUR till 30.09.2011
X69502060,Contract FL1-07 sum of 42,17 USD till 30.09.2011
X79484483,Contract FL1-07 sum of 42,17 USD till 30.09.2011
X69931232,Contract FL2-01/M2 sum of 40,84 EUR till 30.09.2011; FL1-18 sum of  198,45 EUR till 30.11.2011
X79484483,Contract FL2-01/M2 sum of 40,84 EUR till 30.09.2011; FL1-18 sum of  198,45 EUR till 30.11.2011

我当前的XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
Phone,Message
<xsl:for-each select="/message/customer">
<xsl:sort order="ascending" select="contract/@number"/>
<xsl:value-of select="/message/customer/@mobile"/>,
Contract <xsl:value-of select="contract/@number"/> sum of <xsl:value-of select="contract/sum"/>
<xsl:value-of select="contract/currency"/> till <xsl:value-of select="contract/deadline"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

如果移动属性包含多个数字,则两者的文本应相同; 如果每个客户有多个合同,请作为新行发送。在示例文件中,我展示了每种可能的变化。

提前谢谢!!!

1 个答案:

答案 0 :(得分:0)

这在XSLT2中会更容易,但是从1开始,这是使用递归拆分模板的旧方法:

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

 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:for-each select="/message/customer/contract">
   <xsl:sort order="ascending" select="@number"/>
   <xsl:call-template name="split">
    <xsl:with-param name="m" select="../@mobile"/>
    <xsl:with-param name="r">
     <xsl:text>, Contract </xsl:text>
     <xsl:value-of select="@number"/>
     <xsl:text> sum of </xsl:text>
     <xsl:value-of select="sum"/>
     <xsl:value-of select="currency"/>
     <xsl:text> till </xsl:text>
     <xsl:value-of select="deadline"/>
     <xsl:text>&#10;</xsl:text>
    </xsl:with-param>
   </xsl:call-template>
  </xsl:for-each>
 </xsl:template>
 <xsl:template name="split">
  <xsl:param name="m"/>
  <xsl:param name="r"/>
  <xsl:choose>
   <xsl:when test="contains($m,',')">
    <xsl:value-of select="normalize-space(substring-before($m,','))"/>
    <xsl:value-of select="$r"/>
    <xsl:call-template name="split">
     <xsl:with-param name="m" select="substring-after($m,',')"/>
     <xsl:with-param name="r" select="$r"/>
    </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
    <xsl:value-of select="normalize-space($m)"/>
    <xsl:value-of select="$r"/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>
制造

$ saxon csv1.xml csv2.xsl
X69502060, Contract FL1-07 sum of 42,17USD till 30.09.2011
X79484483, Contract FL1-07 sum of 42,17USD till 30.09.2011
X69931232, Contract FL1-18 sum of 198,45EUR till 30.11.2011
X79484483, Contract FL1-18 sum of 198,45EUR till 30.11.2011
X69931232, Contract FL1-22/Ml sum of 21,55USD till 30.09.2011
X79484483, Contract FL1-24 sum of 329,44EUR till 30.12.2011
X79484483, Contract FL1-27 sum of 232,91EUR till 30.12.2011
X69931232, Contract FL2-01/M2 sum of 40,84EUR till 30.09.2011
X79484483, Contract FL2-01/M2 sum of 40,84EUR till 30.09.2011