Thanks, Martin. This is exactly what I needed to get started. I think I can
massage the punctuation after replacing the pipes for choice elements.
-----Original Message-----
From: Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>
Sent: Friday, May 17, 2019 9:41 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Tokenizing mixed content
EXTERNAL
On 17.05.2019 15:29, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de wrote:
On 17.05.2019 15:22, Edward Porter edward(_dot_)porter(_at_)sas(_dot_)com
wrote:
I am working on a conversion script transforming from a prior DTD to
a new DTD, and as part of this transformation, we are hoping to parse
some mixed content into separate nested elements. The content is "|"
delimited, but I am having a tough time coming up with a way to group
the text and sibling elements. What follows are some permutations of
input and expected output:
I've got access to XSL 2, and possibly XSL3 if necessary.
A two pass transformation that first processes text nodes to "convert"
the pipe character into an element (e.g. <pipe/>) and then in second
step uses for-each-group group-ending-with="pipe" should help.
Along the lines of
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="pipe-char-to-pipe-el" on-no-match="shallow-copy"/>
<xsl:mode name="analyze-string"/>
<xsl:template match="text()" mode="pipe-char-to-pipe-el">
<xsl:apply-templates select="analyze-string(., '\s*\|\s*')"
mode="analyze-string"/>
</xsl:template>
<xsl:template match="fn:match" mode="analyze-string">
<pipe/>
</xsl:template>
<xsl:variable name="first-pass-result">
<xsl:apply-templates mode="pipe-char-to-pipe-el"/>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="$first-pass-result/node()"/>
</xsl:template>
<xsl:template match="argument">
<xsl:copy>
<xsl:for-each-group select="node()" group-ending-with="pipe">
<choice>
<xsl:apply-templates select="current-group()"/>
</choice>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="pipe"/>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gWvjQfJ
Not sure when/where the quotes in the first example need to be eliminated.
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--