Re: [xsl] XSLT for CSV to XML Conversion

Subject: Re: [xsl] XSLT for CSV to XML Conversion
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 16 Feb 2019 16:35:28 -0000
On 15.02.2019 18:15, Rahul Singh rahulsinghindia15@xxxxxxxxx wrote:

I wrote XSL code for CSV to XML conversion but i am not getting proper output as for #Id 3 in XML. and, Also I need output as per given expected output below.

Need yours help for given Input CSV, XSL Code, Current Output, Expected Output please:

*Input CSV:*

<root>ID|Value|Number|descr1|descr2|descr3|descr4
1|AAAAA|1|aaaaaaaaaaa|aaaaaaaaaaa|aaaaaaaaaaa|aaaaaaaaaaa
2|AAAAA|2|aaaaaaaaaaa|aaaaaaaaaa|aaaaaaaa|aaaaaaaaaaaa
3|AAAAA|3|aaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|aaaaaaaaaaa|aaaaaaaaaaa|aaaaaaaaaaa</root>

*Expected Output:*

<?xml version="1.0" encoding="UTF-8"?>
<root>
B B <row>
B B B <ID>1</ID>
B B B <Value>AAAAA</Value>
B B B <Number>1</Number>
B B B <descr1>aaaaaaaaaaa</descr1>
B B B <descr2>aaaaaaaaaaa</descr3>
B B B <descr3>aaaaaaaaaaa</descr3>
B B B <descr4>aaaaaaaaaaa</descr4>
B B </row>
B B <row>
B B B <ID>2</ID>
B B B <Value>AAAAA</Value>
B B B <Number>2</Number>
B B B <descr1>aaaaaaaaaaa</descr1>
B B B <descr2>aaaaaaaaaa</descr2>
B B B <descr3>aaaaaaaa</descr3>
B B B <descr4>aaaaaaaaaaaa</descr4>
B B </row>
B B <row>
B B B <Id>3</Id>
B B B <Value>AAAAA</Value>
B B B <Number>3</Number>
<descr1>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</descr1>
B B B <descr2>aaaaaaaaaaa</descr2>
B B B <descr3>aaaaaaaaaaa</descr3>
B B B <descr4>aaaaaaaaaaa</descr4>
B B </row>
</root>

It is not clear why you do not simply use the XPath 2 and later "tokenize" function to break up your text into record or row lines and each record or row into columns.


Here is a suggestion to to it in XSLT 3 (supported by Saxon 9.8 or later):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
	xmlns:xs="http://www.w3.org/2001/XMLSchema";
	exclude-result-prefixes="#all"
	version="3.0">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="root">
<xsl:copy>
<xsl:variable name="lines" as="xs:string*" select="tokenize(., '&#10;')"/>
<xsl:variable name="cols" select="tokenize(head($lines), '\|')"/>
<xsl:apply-templates select="tail($lines)" mode="row">
<xsl:with-param name="cols" select="$cols"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>


<xsl:template match=".[. instance of xs:string]" mode="row">
<xsl:param name="cols"/>
<row>
<xsl:for-each select="tokenize(., '\|')">
<xsl:element name="{let $p := position() return $cols[$p]}" expand-text="yes">{.}</xsl:element>
</xsl:for-each>
</row>
</xsl:template>


</xsl:stylesheet>

Online sample at https://xsltfiddle.liberty-development.net/ncdD7m6

Current Thread