XML to CSV Using XSLT XML to CSV Using XSLT xml xml

XML to CSV Using XSLT


Here is a version with configurable parameters that you can set programmatically:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="text" encoding="utf-8" />  <xsl:param name="delim" select="','" />  <xsl:param name="quote" select="'"'" />  <xsl:param name="break" select="'&#xA;'" />  <xsl:template match="/">    <xsl:apply-templates select="projects/project" />  </xsl:template>  <xsl:template match="project">    <xsl:apply-templates />    <xsl:if test="following-sibling::*">      <xsl:value-of select="$break" />    </xsl:if>  </xsl:template>  <xsl:template match="*">    <!-- remove normalize-space() if you want keep white-space at it is -->     <xsl:value-of select="concat($quote, normalize-space(), $quote)" />    <xsl:if test="following-sibling::*">      <xsl:value-of select="$delim" />    </xsl:if>  </xsl:template>  <xsl:template match="text()" /></xsl:stylesheet>


Found an XML transform stylesheet here (wayback machine link, site itself is in german)

The stylesheet added here could be helpful:

<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>&#xD;</xsl:text></xsl:if></xsl:for-each></xsl:template></xsl:stylesheet>

Perhaps you want to remove the quotes inside the xsl:if tags so it doesn't put your values into quotes, depending on where you want to use the CSV file.


This xsl:stylesheet can use a specified list of column headers and will ensure that the rows will be ordered correctly. It requires XSLT version 2.0.

<?xml version="1.0"?><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv">    <xsl:output method="text" encoding="utf-8"/>    <xsl:strip-space elements="*"/>    <xsl:variable name="delimiter" select="','"/>    <csv:columns>        <column>name</column>        <column>sublease</column>        <column>addressBookID</column>        <column>boundAmount</column>        <column>rentalAmount</column>        <column>rentalPeriod</column>        <column>rentalBillingCycle</column>        <column>tenureIncome</column>        <column>tenureBalance</column>        <column>totalIncome</column>        <column>balance</column>        <column>available</column>    </csv:columns>    <xsl:template match="/property-manager/properties">        <!-- Output the CSV header -->        <xsl:for-each select="document('')/*/csv:columns/*">                <xsl:value-of select="."/>                <xsl:if test="position() != last()">                    <xsl:value-of select="$delimiter"/>                </xsl:if>        </xsl:for-each>        <xsl:text>&#xa;</xsl:text>            <!-- Output rows for each matched property -->        <xsl:apply-templates select="property"/>    </xsl:template>    <xsl:template match="property">        <xsl:variable name="property" select="."/>            <!-- Loop through the columns in order  -->        <xsl:for-each select="document('')/*/csv:columns/*">            <!-- Extract the column name and value  -->            <xsl:variable name="column" select="."/>            <xsl:variable name="value" select="$property/*[name() = $column]"/>                    <!-- Quote the value if required -->            <xsl:choose>                <xsl:when test="contains($value, '"')">                    <xsl:variable name="x" select="replace($value, '"',  '""')"/>                    <xsl:value-of select="concat('"', $x, '"')"/>                </xsl:when>                <xsl:when test="contains($value, $delimiter)">                    <xsl:value-of select="concat('"', $value, '"')"/>                </xsl:when>                <xsl:otherwise>                    <xsl:value-of select="$value"/>                </xsl:otherwise>            </xsl:choose>                    <!-- Add the delimiter unless we are the last expression -->            <xsl:if test="position() != last()">                <xsl:value-of select="$delimiter"/>            </xsl:if>        </xsl:for-each>            <!-- Add a newline at the end of the record -->        <xsl:text>&#xa;</xsl:text>    </xsl:template></xsl:stylesheet>