Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<EmployeeDetails>
    <Employee>
        <FirstName>harry</FirstName>
        <SecondName>potter</SecondName>
        <Email>harrypotter@gmail.com</Email>
    </Employee>
    <Employee>
        <FirstName>tony</FirstName>
        <SecondName>stark</SecondName>
        <Email>tonystark@gmail.com</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,harrypotter@gmail.com,tony,stark,tonystark@gmail.com

Expected output:

FirstName,SecondName,Email 
harry,potter,harrypotter@gmail.com
tony,stark,tonystark@gmail.com

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

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading