[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] transforming a XML to CSV


Subject: RE: [xsl] transforming a XML to CSV
From: "Robert C. Lyons" <boblyons@xxxxxxxxxx>
Date: Wed, 14 Mar 2001 15:38:42 -0500

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>&#10;</xsl:text>
    </xsl:variable>

    <xsl:choose>

    <xsl:when test="contains( $field, '&quot;' )">
      <!-- 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, '&quot;' )" />
    <xsl:text>""</xsl:text>

    <xsl:variable name="substring_after_first_quote"
                  select="substring-after( $string, '&quot;' )" />

    <xsl:choose>

    <xsl:when test="not( contains( $substring_after_first_quote,
'&quot;' ) )">
      <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@xxxxxxxxxx'
     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



Current Thread
Keywords
xml