使用XSLT将XML转换为CSV

时间:2013-05-16 18:00:15

标签: xml xslt csv xslt-1.0

XML IS:

<projects>
    <project>
        <name ID="A" StartDate='2012-01-01' EndDate='2012-01-30'>Shockwave</name> 
        <language>Ruby</language> 
        <Manager ID="M1">Nathan</Manager>
    </project>
    <project>
        <name ID="B" StartDate='2012-01-01' EndDate='2012-02-30'>Other</name> 
        <language>Erlang</language>
        <Manager ID="M2">Kristi</Manager>  
    </project>
</projects>

我想使用XSLT将此XML复制到CSV。有1000个这样的项目。 如何将下面显示的输出转换为csv:

A;2012-01-01;2012-01-30;Shockwave;Ruby;M1;Nathan|B;2012-01-01;2012-02-30;Other;Erlang;M2;Kristi|   

2 个答案:

答案 0 :(得分:1)

使用您链接的解决方案,但更改行

<xsl:for-each select="child::*">

<xsl:for-each select="child::*|attribute::*">

这将选择属性和节点。

答案 1 :(得分:1)

尝试这样的事情。它将在元素文本之前输出任何属性。

XML输入

<projects>
    <project>
        <name ID="A">Shockwave</name> 
        <language>Ruby</language> 
    </project>
    <project>
        <name ID="B">Other</name> 
        <language>Erlang</language>  
    </project>
</projects>

XSLT 1.0

<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="project">
        <xsl:apply-templates select="@*|node()"/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:value-of select="."/>
        <xsl:if test="../text() or parent::project">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:template>

    <xsl:template match="*[ancestor::project]">
        <xsl:apply-templates select="@*"/>
        <xsl:if test="preceding-sibling::*">
            <xsl:text>,</xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
    </xsl:template>

</xsl:stylesheet>

<强>输出

A,Shockwave,Ruby
B,Other,Erlang

编辑新要求

XML输入

<projects>
    <project>
        <name ID="A" StartDate='2012-01-01' EndDate='2012-01-30'>Shockwave</name> 
        <language>Ruby</language> 
        <Manager ID="M1">Nathan</Manager>
    </project>
    <project>
        <name ID="B" StartDate='2012-01-01' EndDate='2012-02-30'>Other</name> 
        <language>Erlang</language>
        <Manager ID="M2">Kristi</Manager>  
    </project>
</projects>

XSLT 1.0

<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="project">
        <xsl:apply-templates select="@*|node()"/>
        <xsl:text>|</xsl:text>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:if test="count(parent::*/@*)=1 and not(parent::project)">
            <xsl:text>;</xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
        <xsl:if test="parent::project or (last())">
            <xsl:text>;</xsl:text>
        </xsl:if>
    </xsl:template>

    <xsl:template match="*[ancestor::project]">
        <xsl:apply-templates select="@*"/>
        <xsl:if test="preceding-sibling::* and not(@*)">
            <xsl:text>;</xsl:text>
        </xsl:if>
        <xsl:value-of select="."/>
    </xsl:template>

</xsl:stylesheet>

<强>输出

A;2012-01-01;2012-01-30;Shockwave;Ruby;M1;Nathan|B;2012-01-01;2012-02-30;Other;Erlang;M2;Kristi|