2012-09-12 105 views
1

以下代碼將xml更改爲csv。xml轉換爲帶有xslt的csv

當它被施加到下面的示例數據

<Addy> 
<Row> 
<L>1</L> 
<LD>Dwelling</LD> 
<Th>Passage</Th> 
</Row> 
</ADDY> 

它產生csv文件在此formatincludng的列名

L,LD,Th 
1,Dwelling,Passage 

想法是與列名做掉並在最後一個值的末尾添加逗號(,) 以使預期結果爲

1,Dwelling,passage, 
+0

你能保證沒有值會有逗號嗎?如果可能發生,你會如何獲得該輸出? – Flynn1179

回答

1

template/刪除

<xsl:for-each select="*/*/*[generate-id() = generate-id(key('field',name())[1])]"> 
    <xsl:value-of select="name()" /> 
    <xsl:if test="position() != last()">,</xsl:if> 
</xsl:for-each> 
<xsl:text>&#10;</xsl:text> 

並添加逗號:在templaterow模式

<xsl:text>,&#10;</xsl:text> 

*

1

如果這些元素均在同一順序爲每那麼你不需要任何複雜的Muenchian分組的,模板模式等的只是一個很簡單的樣式就足夠了:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output method="text"/> 

    <xsl:template match="Row"> 
    <xsl:apply-templates select="*" /> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="Row/*"> 
    <xsl:value-of select="." /> 
    <xsl:text>,</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

運行此在接下來的輸入:

<Addy> 
    <Row> 
    <L>1</L> 
    <LD>Dwelling</LD> 
    <Th>Passage</Th> 
    </Row> 
    <Row> 
    <L>2</L> 
    <LD>Foo</LD> 
    <Th>Bar</Th> 
    </Row> 
</Addy> 

產生輸出你後,包括在最後一列值後的尾部逗號:

1,Dwelling,Passage, 
2,Foo,Bar, 
+0

不完全 - 這留下每一行結尾的逗號... –

+2

@DimitreNovatchev這就是要求的問題... –

0

只需修改模板所以現在匹配/它應該是:

<xsl:template match="/"> 
    <xsl:apply-templates select="*/*" mode="row"/> 
    </xsl:template> 

如果你真的想在生產的每一行的末尾尾隨逗號,然後替換第一次出現:

<xsl:if test="position() != last()">,</xsl:if> 

有:

<xsl:text>&#10;</xsl:text> 

當僅執行這些最小的修改,所提供的代碼變爲:

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

    <xsl:key name="field" match="/*/*/*" use="name()" /> 
    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="*/*" mode="row"/> 
    </xsl:template> 

    <xsl:template match="*" mode="row"> 
    <xsl:variable name="row" select="*" /> 
    <xsl:for-each select="/*/*/*[generate-id() = generate-id(key('field',name())[1])]"> 
     <xsl:variable name="name" select="name()" /> 
     <xsl:apply-templates select="$row[name()=$name]" mode="data" /> 
     <xsl:text>,</xsl:text> 
    </xsl:for-each> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="*" mode="data"> 
    <xsl:choose> 
     <xsl:when test="contains(text(),',')"> 
      <xsl:text>&quot;</xsl:text> 
      <xsl:call-template name="doublequotes"> 
       <xsl:with-param name="text" select="text()" /> 
      </xsl:call-template> 
      <xsl:text>&quot;</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="." /> 
     </xsl:otherwise> 
    </xsl:choose> 
    <xsl:if test="position() != last()">,</xsl:if> 
    </xsl:template> 

    <xsl:template name="doublequotes"> 
    <xsl:param name="text" /> 
    <xsl:choose> 
     <xsl:when test="contains($text,'&quot;')"> 
      <xsl:value-of select="concat(substring-before($text,'&quot;'),'&quot;&quot;')" /> 
      <xsl:call-template name="doublequotes"> 
       <xsl:with-param name="text" select="substring-after($text,'&quot;')" /> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text" /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

當在下面的XML文檔被應用該轉化(注意在這兩個元件不同的順序的孩子)

<Addy> 
    <Row> 
    <L>1</L> 
    <LD>Dwelling</LD> 
    <Th>Passage</Th> 
    </Row> 
    <Row> 
    <Th>Bar</Th> 
    <LD>Foo</LD> 
    <L>2</L> 
    </Row> 
</Addy> 

想要的,正確的結果產生

1,Dwelling,Passage, 
2,Foo,Bar, 
+0

@lee,輸出行已經編號 - 你的意思是別的嗎? –

+0

@lee,哦,我明白了。下班後我可以在大約9小時後看看這個。 –

+0

@lee,我確實看過這個問題,但很難理解你想要什麼... –