我必须将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>
如果移动属性包含多个数字,则两者的文本应相同; 如果每个客户有多个合同,请作为新行发送。在示例文件中,我展示了每种可能的变化。
提前谢谢!!!
答案 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> </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