2012-03-16 138 views
0

我必须将XML转换为CSV,但对我而言,转换是相当困难的。每个周期的XSLT?

这是一个示例XML:

<?xml version="1.0" encoding="windows-1251"?> 
    <message text="Contract [number] of [sum] [currency] till [deadline]" report="[email protected]"> 
    <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

您的CSV坏了,逗号在货币将导致场分裂。另外,你不相信缩进吗?请修改您的帖子并正确缩进XML和XSLT。 – 2012-03-16 16:27:04

回答

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 
+0

我认为这产生了什么问题,但(a)您的样本结果使用;而不是在某些情况下使用换行符,并且(b)您可能希望在总和字段中放置“”,因为它包含逗号。但其中任何一个应该是一个微不足道的变化,这取决于你所需要的。 – 2012-03-16 16:50:04

+0

是的,谢谢!它运行良好,我不得不追加一些额外的东西,但这个想法很棒。 :) – iulikchip 2012-04-20 20:13:34