2012-11-27 71 views
0

我想從以下形式的XML文件進行CSV創建CSV:如何使用XSLT從XML

<?xml version="1.0" encoding="UTF-8"?> 
    <Envelope> 
     <Header> 
      <env:MessageSentDateTime>2012-09-19T09:50:04Z</env:MessageSentDateTime> 
      <env:MessageSequenceNumber>856432</env:MessageSequenceNumber> 
     </Header> 
     <Body> 
      <Data> 
       <Data:ID> 
        <Data:AODB>9346280</Data:AODB> 
        <Data:Ref> 
         <common:Code>HJ</common:Code> 
         <common:num>8113</common:num> 
        </Data:Ref> 
       </Data:ID> 
       ... Continues like this, no set number of nodes, parts or AnotherParts 
     </Body> 
     Second message starting with <Header> ending with </Body>, 
     will be more than 2 in practice 
    </Envelope> 

我想提出一個換行符CSV文件在/身體標籤因爲這表示一條新消息。在正文部分中會有不同數量的節點,不同數量的部分和不一致的末端節點的消息混合。另外,將會有不包含任何文本的節點,但我仍然需要逗號。

到目前爲止,我有:

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

     <xsl:template match="*[not(*)]"> 
      <xsl:value-of select="normalize-space(.)"/> 
      <xsl:text>,</xsl:text> 
     </xsl:template> 

     <xsl:template match="Body[last()]"> 
      <xsl:value-of select="normalize-space(.)"/> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:template> 
    </xsl:stylesheet> 

它還在機身的最後一條信息後加逗號。我想用換行符替換那個逗號,有沒有簡單的方法來做到這一點?

問候, 大衛

+0

試試這個:http://stackoverflow.com/questions/3056579/convert-xml-document-to-comma-delimited-csv-file-using-xslt-stylesheet –

回答

0

我的規格略有改變,需要的節點路徑和值,以使每個條目唯一的。這是我用來解決我的問題的代碼:

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

    <xsl:template match="*[*]"> 
     <xsl:param name="elementNames" select="''"/> 
     <xsl:apply-templates select="*"> 
      <xsl:with-param name="elementNames"> 
       <xsl:copy-of select="$elementNames"/> 
       <xsl:value-of select="replace(name(.), ':', '.')"/> 
       <xsl:text>_</xsl:text> 
      </xsl:with-param> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="*[not (*)]"> 
     <xsl:param name="elementNames" select="''"/> 
     <xsl:copy-of select="$elementNames"/> 
     <xsl:value-of select="replace(name(.), ':', '.')"/> 
     <xsl:value-of select="name()"/>,<xsl:apply-templates select="current()/text()"/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

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

謝謝大家誰看了,並試圖幫助。

問候, 大衛

0

一種方法可以更改模板的身體元件匹配具體來看爲「葉」的子元素

<xsl:template match="Body"> 
    <xsl:apply-templates select=".//*[not(*)]"/> 
    <xsl:text>&#10;</xsl:text> 
</xsl:template> 

然後,在你的模板匹配葉子元素,如果它不是第一個元素,則可以將其更改爲僅輸出逗號

<xsl:if test="position() &gt; 1"> 
    <xsl:text>,</xsl:text> 
    </xsl:if> 

下面是完整的XSLT,如果你想給它一個去:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*[not(*)]"> 
     <xsl:if test="position() &gt; 1"> 
     <xsl:text>,</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="normalize-space(.)"/> 
    </xsl:template> 

    <xsl:template match="Body"> 
     <xsl:apply-templates select=".//*[not(*)]"/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 
+0

喜添C,謝謝你的回覆。這段代碼用最後的逗號排序問題,但它不會在輸出中給我一個新行 –

+0

您可以嘗試在XSLT中用'NEWLINE'替換' ',因爲這將證明模板匹配** Body * *實際上正在使用。另外,如果你編輯你的問題來顯示一個XML實例的完整例子(雖然不是太大!),它會有所幫助。謝謝! –

+0

我試着用NEWLINE替換,模板沒有被使用。我用一些實際的xml數據編輯了這個問題 –