Last active
August 31, 2020 10:16
-
-
Save rnelson/395bccd30092cedca87f to your computer and use it in GitHub Desktop.
Tokenize a string in XSLT 1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<input fields="One|Two|Three|Four|Five|Agree" values="Answer A|Answer B|Answer C|Answer D|Answer E|Yes"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ xsltproc stylesheet.xslt input.xml | |
<?xml version="1.0"?> | |
<Output><FirstField><FieldName>One</FieldName><FieldValue>Answer A</FieldValue></FirstField><LastField><FieldName>Agree</FieldName><FieldValue>Yes</FieldValue></LastField></Output> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<xsl:stylesheet | |
version="1.1" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns:ext="http://exslt.org/common" | |
exclude-result-prefixes="ext"> | |
<!-- Tokenize a string that's pipe separated --> | |
<xsl:template name="tokenize"> | |
<xsl:param name="text"/> | |
<xsl:param name="separator" select="'|'"/> | |
<xsl:choose> | |
<xsl:when test="not(contains($text, $separator))"> | |
<item> | |
<xsl:value-of select="normalize-space($text)"/> | |
</item> | |
</xsl:when> | |
<xsl:otherwise> | |
<item> | |
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/> | |
</item> | |
<xsl:call-template name="tokenize"> | |
<xsl:with-param name="text" select="substring-after($text, $separator)"/> | |
</xsl:call-template> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:template> | |
<xsl:template match="/input"> | |
<!-- Tokenize the 'fields' attribute on /input --> | |
<xsl:variable name="name-set"> | |
<xsl:call-template name="tokenize"> | |
<xsl:with-param name="text"> | |
<xsl:value-of select="@fields"/> | |
</xsl:with-param> | |
</xsl:call-template> | |
</xsl:variable> | |
<!-- Tokenize the 'values' attribute on /input --> | |
<xsl:variable name="value-set"> | |
<xsl:call-template name="tokenize"> | |
<xsl:with-param name="text"> | |
<xsl:value-of select="@values"/> | |
</xsl:with-param> | |
</xsl:call-template> | |
</xsl:variable> | |
<!-- Generate our output --> | |
<Output> | |
<FirstField> | |
<FieldName><xsl:copy-of select="ext:node-set($name-set)/item[1]/text()"/></FieldName> | |
<FieldValue><xsl:copy-of select="ext:node-set($value-set)/item[1]/text()"/></FieldValue> | |
</FirstField> | |
<LastField> | |
<FieldName><xsl:copy-of select="ext:node-set($name-set)/item[last()]/text()"/></FieldName> | |
<FieldValue><xsl:copy-of select="ext:node-set($value-set)/item[last()]/text()"/></FieldValue> | |
</LastField> | |
</Output> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
Thanks for this code.
Just a remark: I think you forgot to insert $separator parameter when you recursively call tokenize template.
If you don't, it doesn't work if your separator is not a pipe.