I am attempting to take an XML file and convert it with XSLT.
The XML I am trying to convert looks like this:
<root>
<TAG>10, 1, 3, 123, 4001, 34, 200, 105, 54, 0, 0, 0</TAG>
</root>
When I run the conversion, I would like the result to appear like this:
<Field1>10</Field1>
<Field2>1</Field2>
...
<Field12>0</Field12>
However, my XSLT file is not working like designed.
Whenever I run the converter, I get back this as a response:
<Field_1>
<TAG>10, 1, 3, 123, 4001, 34, 200, 105, 54, 0, 0, 0</TAG>
</Field_1>
Here is my XSLT file:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kml="http://www.opengis.net/kml/2.2" version="1.0">
<xsl:strip-space elements = "*"/>
<xsl:output method = "xml" indent = "yes"/>
<xsl:template match = "@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:call-template name="listItem">
<xsl:with-param name="tag" select="TAG"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="listItem">
<xsl:param name="features"/>
<xsl:choose>
<xsl:when test="contains($features, ',')">
<xsl:element name="Field_{position()}">
<xsl:apply-templates select="@*|node()"/>
<xsl:value-of select="normalize-space(substring-before($features, ','))"/>
<xsl:variable name="nextValue" select="substring-after($features, ',')"/>
</xsl:element>
<xsl:if test="normalize-space($nextValue)">
<xsl:call-template name="listItem">
<xsl:with-param name="features" select="$nextValue"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Field_{position()}">
<xsl:apply-templates select="@*|node()"/>
<xsl:value-of select="$features"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Does anyone have any suggestions for how to get my XSLT file to convert my XML into the desired result?
Please and thanks for your help.
Use this XSLT.
It is XSLT version 1.0 and uses recursion via a named <xsl:template>
called field
to delimit the comma-separated values and encapsulate each of the values in <Field>
elements. The element's name is generated of the static string Field
plus a recursively passed variable named cnt
.
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="/root">
<root>
<xsl:call-template name="field">
<xsl:with-param name="cnt" select="1" />
<xsl:with-param name="txt" select="concat(TAG/text(),',')" />
</xsl:call-template>
</root>
</xsl:template>
<xsl:template name="field">
<xsl:param name="cnt" />
<xsl:param name="txt" />
<xsl:element name="{concat('Field',$cnt)}">
<xsl:value-of select="normalize-space(substring-before($txt,','))"/>
</xsl:element>
<xsl:if test="normalize-space(substring-after($txt,',')) != ''">
<xsl:call-template name="field">
<xsl:with-param name="cnt" select="$cnt + 1" />
<xsl:with-param name="txt" select="substring-after($txt,',')" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The result - as desired - is:
<?xml version="1.0"?>
<root>
<Field1>10</Field1>
<Field2>1</Field2>
<Field3>3</Field3>
<Field4>123</Field4>
<Field5>4001</Field5>
<Field6>34</Field6>
<Field7>200</Field7>
<Field8>105</Field8>
<Field9>54</Field9>
<Field10>0</Field10>
<Field11>0</Field11>
<Field12>0</Field12>
</root>