2016-03-19 28 views
0

我想通過使用「;」將我的自定義XML轉換爲csv。作爲值分隔符。這裏是我的XML:XSLT將我的自定義XML轉換爲CSV

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <operators> 
     <item> 
      <lfbis>1234567</lfbis> 
      <name>Stefan Maier</name> 
      <company /> 
      <street>Testweg 7</street> 
      <citycode>95131</citycode> 
      <city>Hof</city> 
      <controlbody>BIKO</controlbody> 
      <productdata> 
       <item>Rinder</item> 
       <item>9</item> 
      </productdata> 
     </item> 
     <item> 
      <lfbis>5671234</lfbis> 
      <name>Antom Mueller</name> 
     <company>Berghof</company> 
      <street>Testweg 8</street> 
      <citycode>95111</citycode> 
      <city>Bamberg</city> 
      <controlbody>BIKO</controlbody> 
      <productdata> 
       <item>Rinder</item> 
       <item>9</item> 
      </productdata> 
     </item> 
    </operators> 
</root> 

我迄今管理(使用計算器線程 XML to CSV Using XSLT,尤其是使用代碼在他的回答...a version with configurable parameters that you can set programmatically寫道通過@Tomalak)使用以下XSLT轉換:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="utf-8" /> 

    <xsl:param name="delim" select="';'" /> 
    <xsl:param name="quote" select="'&quot;'" /> 
    <xsl:param name="break" select="'&#xA;'" /> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="root/operators/item" /> 
    </xsl:template> 

    <xsl:template match="item"> 
    <xsl:apply-templates /> 
    <!--<xsl:if test="following-sibling::*">--> 
     <xsl:value-of select="concat($delim, $break)" /> 
    <!--</xsl:if>--> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:value-of select="normalize-space()" /> 
    <xsl:if test="following-sibling::*"> 
     <xsl:value-of select="$delim" /> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="text()" /> 

</xsl:stylesheet> 

...,我使用xsltproc的得到以下結果:

1234567;Stefan Maier;;Testweg 7;95131;Hof;BIKO;Rinder 9; 
5671234;Antom Mueller;Berghof;Testweg 8;95111;Bamberg;BIKO;Rinder 9; 

現在,我想實現的是, 項目產品數據元素的子元素也被視爲csv結果中的值。所以我需要一個「;」而不是 「」(空格)的值Rinder和之間,比如我的CSV會是什麼樣子:

1234567;Stefan Maier;;Testweg 7;95131;Hof;BIKO;Rinder;9; 
5671234;Antom Mueller;Berghof;Testweg 8;95111;Bamberg;BIKO;Rinder;9; 
+2

如果您要使用其他人的代碼,請至少聲明他們而不是說你寫了它。您可以從http://stackoverflow.com/a/365372/18771獲取XSLT代碼。 – Tomalak

+0

是的,對不起,我當然使用了stackoverflow線程來編寫xlst樣式表。我向那個線程中的人們道歉,特別是對於樣式表的作者,在我的問題中沒有提及他。我將在未來的職位更加小心。 –

回答

1

這裏是託默勒格的代碼適應

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

    <xsl:output method="text" encoding="utf-8" /> 

    <xsl:param name="delim" select="';'" /> 
    <xsl:param name="quote" select="'&quot;'" /> 
    <xsl:param name="break" select="'&#xA;'" /> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="root/operators/item" /> 
    </xsl:template> 

    <xsl:template match="root/operators/item"> 
    <xsl:apply-templates select=".//*[not(*)]"/> 
    <xsl:value-of select="$break" /> 
    </xsl:template> 

    <xsl:template match="*"> 
    <xsl:if test="position() > 1"> 
     <xsl:value-of select="$delim"/> 
    </xsl:if> 
    <xsl:value-of select="normalize-space()" /> 
    </xsl:template> 

    <xsl:template match="text()" /> 

</xsl:stylesheet> 

當你有兩種類型item元素我需要一個相當明確的匹配模式。

+0

感謝Martin,我使用了@Tomalak的代碼,並且xml get以我想要的方式改變了方向。我在匹配_root/operators/item_元素的模板中添加了'select =「concat($ delim,$ break)」',以便在每行的最後一個值之後加上一個分號。 –

2

一個簡單的方法是改變

<xsl:template match="*"> 

<xsl:template match="*[not(*)]"> 
它匹配沒有一個子元素元素

。其效果是,當apply-templates訪問productData元素時,沒有匹配的模板規則,因此默認啓動,即將模板應用於子項。

但是這需要改變處理分隔符的策略。在你的情況下,這很容易,因爲你需要在包含最後一個項目的每一項之後使用分號:所以在輸出每個項目後無條件地添加分號,並且不要在該行的末尾添加另一個分號。

+0

謝謝邁克爾指引我在正確的方向! –