This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: transforming a XML to CSV
- To: <xsl-list at lists dot mulberrytech dot com>, <Anand_Awasthi at bmc dot com>
- Subject: RE: [xsl] transforming a XML to CSV
- From: "Robert C. Lyons" <boblyons at unidex dot com>
- Date: Wed, 14 Mar 2001 15:38:42 -0500
- Reply-To: xsl-list at lists dot mulberrytech dot com
The solutions presented so far assume that
the field values will not contain any commas,
linefeeds or quotes.
In a CSV file, if a field value contains
a comma or a linefeed or a quote, then
it must be enclosed in quotes.
Also, if a field value contains quotes,
then an extra quote must be inserted in
front of each quote.
I updated Evan's solution to handle field
values that contain a comma, linefeed or
quote:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="/REPORT_ITEMS/REPORT_ITEM"/>
</xsl:template>
<xsl:template match="REPORT_ITEM">
<xsl:apply-templates select="DATA">
<xsl:with-param name="itemNo" select="position()"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="DATA">
<xsl:param name="itemNo"/>
<xsl:call-template name="display_csv_field">
<xsl:with-param name="field" select="../HEADER/REPORT"/>
</xsl:call-template>
<xsl:text>,</xsl:text>
<xsl:value-of select="$itemNo"/>
<xsl:text>,</xsl:text>
<xsl:call-template name="display_csv_field">
<xsl:with-param name="field" select="../HEADER/UOM"/>
</xsl:call-template>
<xsl:text>,</xsl:text>
<xsl:apply-templates select="*"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*">
<xsl:call-template name="display_csv_field">
<xsl:with-param name="field" select="."/>
</xsl:call-template>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template name="display_csv_field">
<xsl:param name="field"/>
<xsl:variable name="linefeed">
<xsl:text> </xsl:text>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains( $field, '"' )">
<!-- Field contains a quote. We must enclose this field in quotes,
and we must escape each of the quotes in the field value.
-->
<xsl:text>"</xsl:text>
<xsl:call-template name="escape_quotes">
<xsl:with-param name="string" select="$field" />
</xsl:call-template>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:when test="contains( $field, ',' ) or
contains( $field, $linefeed )" >
<!-- Field contains a comma and/or a linefeed.
We must enclose this field in quotes.
-->
<xsl:text>"</xsl:text>
<xsl:value-of select="$field" />
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<!-- No need to enclose this field in quotes.
-->
<xsl:value-of select="$field" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="escape_quotes">
<xsl:param name="string" />
<xsl:value-of select="substring-before( $string, '"' )" />
<xsl:text>""</xsl:text>
<xsl:variable name="substring_after_first_quote"
select="substring-after( $string, '"' )" />
<xsl:choose>
<xsl:when test="not( contains( $substring_after_first_quote,
'"' ) )">
<xsl:value-of select="$substring_after_first_quote" />
</xsl:when>
<xsl:otherwise>
<!-- The substring after the first quote contains a quote.
So, we call ourself recursively to escape the quotes
in the substring after the first quote.
-->
<xsl:call-template name="escape_quotes">
<xsl:with-param name="string" select="$substring_after_first_quote"
/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Best regards,
Bob
<sig name = 'Bob Lyons'
title = 'E-Commerce Consultant'
company = 'Unidex, Inc.'
phone = '+1-732-975-9877'
email = 'boblyons@unidex.com'
url = 'http://www.unidex.com/'
product = 'XML Convert: transforms flat files to XML and vice versa' />
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list