2012-03-16 3 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> 

Если атрибут mobile содержит более одного номера, текст должен быть одинаковым для обоих; Если на одного клиента имеется более одного контракта, отправьте его как новую строку. В файле примера я показал все возможные варианты.

Заранее спасибо!

+0

Ваш CSV сломана, запятая в валюте будет происходить разделение поля. Кроме того, разве вы не верите в отступы? Измените свой пост и правильно отделите XML и XSLT. –

ответ

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

Я думаю, что это создало то, что было задано, но (а) использует ваши образцы результатов; а не в новой строке в некоторых случаях, и (б) вы, вероятно, захотите поставить «» вокруг поля суммы, так как оно содержит запятые. Но любой из них должен быть тривиальным изменением, в зависимости от того, что вам нужно. –

+0

Да, спасибо! он отлично работал, мне пришлось добавить некоторые дополнительные вещи, но идея была блестящей. :) – iulikchip

Смежные вопросы