2010-05-17 86 views
6

我想使用XSLT把XML轉換成CSV,但是從SO線程題爲XML To CSV XSLT對我的輸入應用XSL時:XML到CSV使用XSLT幫助

 
<WhoisRecord> 
    <DomainName>127.0.0.1</DomainName> 
    <RegistryData> 
    <AbuseContact> 
     <Email>[email protected]</Email> 
     <Name>Internet Corporation for Assigned Names and Number</Name> 
     <Phone>+1-310-301-5820</Phone> 
    </AbuseContact> 
    <AdministrativeContact i:nil="true"/> 
    <BillingContact i:nil="true"/> 
    <CreatedDate/> 
    <RawText>...</RawText> 
    <Registrant> 
     <Address>4676 Admiralty Way, Suite 330</Address> 
     <City>Marina del Rey</City> 
     <Country>US</Country> 
     <Name>Internet Assigned Numbers Authority</Name> 
     <PostalCode>90292-6695</PostalCode> 
     <StateProv>CA</StateProv> 
    </Registrant> 
    <TechnicalContact> 
     <Email>[email protected]</Email> 
     <Name>Internet Corporation for Assigned Names and Number</Name> 
     <Phone>+1-310-301-5820</Phone> 
    </TechnicalContact> 
    <UpdatedDate>2010-04-14</UpdatedDate> 
    <ZoneContact i:nil="true"/> 
    </RegistryData> 
</WhoisRecord> 

我結束了:

[email protected] Corporation for Assigned Names and Number+1-310-301-5820, 
    , 
    , 
    , 
    ...,  
    4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA,  
    [email protected] Corporation for Assigned Names and Number+1-310-301-5820,  
    2010-04-14, 

我的問題是,產生的轉換缺少節點(如包含IP地址的DomainName元素)和一些子節點沒有逗號(如AbuseContact的子節點)連接在一起。

我希望看到所有以CSV格式輸出的XML輸出,以及以逗號分隔的字符串:「[email protected] Corporation for Assigned Names and Number + 1-310-301-5820」。

我的XSL是相當生疏。感謝您的幫助。 :)

下面是我使用的XSL:

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

<xsl:strip-space elements="*" /> 

<xsl:template match="/*/child::*"> 
    <xsl:for-each select="child::*"> 
    <xsl:if test="position() != last()"><xsl:value-of select="normalize-space(.)"/>, </xsl:if> 
    <xsl:if test="position() = last()"><xsl:value-of select="normalize-space(.)"/><xsl:text>
</xsl:text> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 
+1

很好的問題(+1)。查看我的答案獲得簡單的解決方案。 :) – 2010-05-17 18:50:20

回答

3

這個簡單的變換產生的通緝的結果

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

    <xsl:template match="/"> 
    <xsl:apply-templates select="//text()"/> 
    </xsl:template> 

    <xsl:template match="text()"> 
     <xsl:copy-of select="."/> 
     <xsl:if test="not(position()=last())">,</xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

請注意使用:

<xsl:strip-space elements="*"/> 

放棄任何空白,只有文本節點。

更新:AJ提出了這樣的問題,即結果應該按照每行的recirds/tuple進行分組。它沒有在問題中定義什麼是記錄/元組。因此,當前的解決方案解決了白色空間僅文本節點和失蹤逗號的兩個問題,但目的並不是要GROP輸出到記錄/元組。

+0

CSV不需要一個新行來分隔一組記錄? – 2010-05-17 18:58:52

+2

從這個問題中我們不清楚構成記錄元組是什麼 - 這在關係數據庫世界中具有意義,但是對於樹需要明確定義。我還編輯了我的答案以反映您的評論。 – 2010-05-17 19:34:54

+0

謝謝你們! 我想要一個記錄集/元組。那會有多難?我還希望能夠將XSL應用於類似結構化的XML文檔 - 不推薦按名稱引用元素的解決方案。再次感謝。 :) – 2010-05-18 00:06:33

0

我相信,你需要遞歸解決方案,以解決這個問題。所以,你需要一些能夠潛入樹中直到到達text()節點的東西。如果該text()節點實際上是最後一個節點的子節點,那麼它會放入一個新行。否則,它只是用逗號來表示值。

如果節點不具有文本()節點作爲其子,然後遞歸開始挖成樹。

<xsl:strip-space elements="*" />  

<xsl:template name="rec">   
    <xsl:param name="node"/>   
    <xsl:for-each select="child::*"> 
     <xsl:choose> 
      <xsl:when test="child::text()"> 
       <xsl:choose>       
        <xsl:when test="local-name(.) != 'UpdatedDate'">"<xsl:value-of select="normalize-space(.)"/>", </xsl:when> 
        <xsl:otherwise>"<xsl:value-of select="normalize-space(.)"/>" <xsl:text>&#xD;</xsl:text></xsl:otherwise> 
       </xsl:choose>      
      </xsl:when> 
      <xsl:when test="child::node()"> 
       <xsl:call-template name="rec"> 
        <xsl:with-param name="node" select="child::node()"/> 
       </xsl:call-template>      
      </xsl:when> 
     </xsl:choose> 

    </xsl:for-each> 
</xsl:template> 

這是騙不了的證據,但它產生在我結束這個結果與撒克遜:

"127.0.0.1", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "...", "4676 Admiralty Way, Suite 330", "Marina del Rey", "US", "Internet Assigned Numbers Authority", "90292-6695", "CA", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "2010-04-14" 

希望這有助於。

+0

爲什麼我的回答被拒絕了?有關它的評論會有幫助。我自己是XSLT的新手。 – 2010-05-17 18:54:59

+1

可能是因爲沒有明確的遞歸或循環需要沿着子軸移動。 – Tomalak 2010-05-18 09:30:50