Search

In trying to solve one problem, I seem to have solved a much more general problem: converting a list of comma-separated values into XML that can be evaluated by an XSL template as XML nodes rather than text strings. I have modified this template to take two parameters:

  • $input is the list of values separated by commas
  • $element-name is the name of the XML elements (the value must be wrapped in single quotes)

Here's the basic CSV to XML template

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

<xsl:output method='html' version='1.0' encoding='utf-8' indent='no'/>

<xsl:param name="csv">
  Intro, Section, Subsection, Subsubsection, Body, Appendix, Line Items
</xsl:param>

<xsl:template match="/">
  <xsl:param name="xml">
    <xsl:call-template name="xml">
      <xsl:with-param name="input" select="$csv"/>
      <xsl:with-param name="element-name" select="'option'"/>
    </xsl:call-template>
  </xsl:param>
  <xsl:copy-of select="$xml/*"/>
</xsl:template>

<xsl:template name="xml">
  <xsl:param name="input"/>
  <xsl:param name="element-name"/>
  <xsl:param name="value" select="normalize-space(substring-before($input,','))"/>
  <xsl:param name="remaining-values" select="normalize-space(substring-after($input,','))"/>
  <xsl:if test="$remaining-values != ''">
    <xsl:element name="{$element-name}">
      <xsl:value-of select="$value"/>
    </xsl:element>
    <xsl:call-template name="xml">
      <xsl:with-param name="input" select="$remaining-values"/>
      <xsl:with-param name="element-name" select="$element-name"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Here's how you can use this template to evaluate nodes to add an attribute, for example, to add a selected attribute to a list of select options:

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>

<xsl:output method='html' version='1.0' encoding='utf-8' indent='no'/>

<xsl:param name="csv">
  Intro, Section, Subsection, Subsubsection, Body, Appendix, Line Items
</xsl:param>

<xsl:template match="/">
  <xsl:param name="selected" select="'Section'"/>
  <xsl:param name="options">
    <xsl:call-template name="xml">
      <xsl:with-param name="input" select="$csv"/>
      <xsl:with-param name="element-name" select="'option'"/>
    </xsl:call-template>
  </xsl:param>
  <xsl:for-each select="$options/option">
    <option value="{.}">
      <xsl:if test=". = $selected">
        <xsl:attribute name="selected">selected</xsl:attribute>
      </xsl:if>
      <xsl:value-of select="."/>
    </option>
  </xsl:for-each>
</xsl:template>

<xsl:template name="xml">
  <xsl:param name="input"/>
  <xsl:param name="element-name"/>
  <xsl:param name="value" select="normalize-space(substring-before($input,','))"/>
  <xsl:param name="remaining-values" select="normalize-space(substring-after($input,','))"/>
  <xsl:if test="$remaining-values != ''">
    <xsl:element name="{$element-name}">
      <xsl:value-of select="$value"/>
    </xsl:element>
    <xsl:text>
</xsl:text>
    <xsl:call-template name="xml">
      <xsl:with-param name="input" select="$remaining-values"/>
      <xsl:with-param name="element-name" select="$element-name"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details