I am are trying to convert an CSV (comma separated file) into XML. For this, I am coding an XSLT template and this is my 1st try at XSLT...
CSV sample:
ClaimRef,HandlerRef,ClaimType,Date,Area,SettleDate,ClaimStatus,ClaimantName
1,1/1,Liability,08-12-2013,US,23-05-2014,Closed,Mark
2,1/2,Liability,08-10-2013,UK,23-02-2014,Closed,John
Desired XML Output format:
<Claims>
<Claim>
<ClaimRef></ClaimRef>
<HandlerRef></HandlerRef>
<ClaimType></ClaimType>
<Date></Date>
<Area></Area>
<SettleDate></SettleDate>
<ClaimStatus></ClaimStatus>
<ClaimantName></ClaimantName>
</Claim>
</Claims>
I used http://blogs.msdn.com/b/kaevans/archive/2003/04/17/5780.aspx as initial start and http://xslttest.appspot.com/ to test the results. But this article mentions how to get the values as <row><elem>, etc
.
Please can you guide me how to code an XSLT to generate above XML based on sample CSV data.
Here's an XSLT 2.0 option...
CSV Input (so.csv referenced in the csv-uri
param.)
ClaimRef,HandlerRef,ClaimType,Date,Area,SettleDate,ClaimStatus,ClaimantName
1,1/1,Liability,08-12-2013,US,23-05-2014,Closed,Mark
2,1/2,Liability,08-10-2013,UK,23-02-2014,Closed,John
XSLT 2.0 (Use either a well-formed dummy XML doc or the stylesheet itself as input or specify csv2xml
as the initial template.)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="csv-encoding" as="xs:string" select="'iso-8859-1'"/>
<xsl:param name="csv-uri" as="xs:string" select="'file:///C:/Users/dhaley/Desktop/so.csv'"/>
<xsl:template match="/" name="csv2xml">
<Claims>
<xsl:choose>
<xsl:when test="unparsed-text-available($csv-uri, $csv-encoding)">
<xsl:variable name="csv" select="unparsed-text($csv-uri, $csv-encoding)"/>
<!--Get Header-->
<xsl:variable name="header-tokens" as="xs:string*">
<xsl:analyze-string select="$csv" regex="\r\n?|\n">
<xsl:non-matching-substring>
<xsl:if test="position()=1">
<xsl:copy-of select="tokenize(.,',')"/>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:analyze-string select="$csv" regex="\r\n?|\n">
<xsl:non-matching-substring>
<xsl:if test="not(position()=1)">
<Claim>
<xsl:for-each select="tokenize(.,',')">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{$header-tokens[$pos]}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</Claim>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="error">
<xsl:text>Error reading "</xsl:text>
<xsl:value-of select="$csv-uri"/>
<xsl:text>" (encoding "</xsl:text>
<xsl:value-of select="$csv-encoding"/>
<xsl:text>").</xsl:text>
</xsl:variable>
<xsl:message><xsl:value-of select="$error"/></xsl:message>
<xsl:value-of select="$error"/>
</xsl:otherwise>
</xsl:choose>
</Claims>
</xsl:template>
</xsl:stylesheet>
XML Output
<Claims>
<Claim>
<ClaimRef>1</ClaimRef>
<HandlerRef>1/1</HandlerRef>
<ClaimType>Liability</ClaimType>
<Date>08-12-2013</Date>
<Area>US</Area>
<SettleDate>23-05-2014</SettleDate>
<ClaimStatus>Closed</ClaimStatus>
<ClaimantName>Mark</ClaimantName>
</Claim>
<Claim>
<ClaimRef>2</ClaimRef>
<HandlerRef>1/2</HandlerRef>
<ClaimType>Liability</ClaimType>
<Date>08-10-2013</Date>
<Area>UK</Area>
<SettleDate>23-02-2014</SettleDate>
<ClaimStatus>Closed</ClaimStatus>
<ClaimantName>John</ClaimantName>
</Claim>
</Claims>
Update per comment...
Here is the same example, but using a variable instead of an external CSV file. You can use this XSLT to test in other online test tools that support XSLT 2.0.
Example on xsltransform.net