codey_08
codey_08

Reputation: 249

Converting XML to CSV formate using XSLT

In my case, I'm trying to convert the XML to CSV format using XSLT.

But I'm getting the header, which is also iterating and printing again, and I also couldn't add a new line to the values column.

XML input:

<EmployeeDetails>
    <Employee>
        <FirstName>harry</FirstName>
        <SecondName>potter</SecondName>
        <Email>[email protected]</Email>
    </Employee>
    <Employee>
        <FirstName>tony</FirstName>
        <SecondName>stark</SecondName>
        <Email>[email protected]</Email>
    </Employee>
</EmployeeDetails>

My XLST code :

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

<xsl:template match="/">
    <xsl:variable name="data" select="//*[not(*)]" />
    <!-- header -->
    <xsl:for-each select="$data">
        <xsl:value-of select="name()" />
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="$data">
        <xsl:value-of select="." />
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

The Output i'm getting for the above XSLT code:

FirstName,SecondName,Email,FirstName,SecondName,Email harry,potter,[email protected],tony,stark,[email protected]

Expected output:

FirstName,SecondName,Email 
harry,potter,[email protected]
tony,stark,[email protected]

Any ideas on above xslt, please assist me and thanks in advance!

Upvotes: 0

Views: 85

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116959

I would suggest you abandon the attempt to make this completely generic and do :

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

<xsl:template match="/EmployeeDetails">
    <!-- header -->
    <xsl:for-each select="Employee[1]/*">
        <xsl:value-of select="name()" />
        <xsl:if test="position()!=last()">,</xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="Employee">
        <xsl:for-each select="*">
            <xsl:value-of select="." />
            <xsl:if test="position()!=last()">,</xsl:if>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Note that this is assuming there won't be any commas, quotation marks or line breaks within the data. And of course, that all children of Employee are leaf nodes.

Upvotes: 1

Related Questions