简体   繁体   中英

XSLT-1.0: Convert comma-separated values to element values

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM