James Cummings wrote:
Ok, I've been beating my brains out against this one for awhile trying
recursive analyze-string and replace() techniques in XSLT2 but just
can't get it to do what I want.
Let's say I have some input like:
====
<root>
<ab type="foo">
<seg>abc def abc+def</seg><lb/>
<seg>+def abcdef foo+def=blah</seg><lb/>
<seg>foo+def=blah</seg>
</ab>
<ab type="foo">
<seg>ab de ac+def</seg><lb/>
<seg>+cdef abdef foo+def=blah</seg><lb/>
<seg>foo+cdef=blah</seg>
</ab>
</root>
====
What I want to do is go through a lookup table of replacements for
certain strings in the text of the seg elements. The replacements are
stored something like:
====
<root>
<choice>
<abbr>abc</abbr>
<expan>
<w>ab<m>c</m></w>
</expan>
</choice>
<choice>
<abbr>foo+def=blah</abbr>
<expan>
<w>foo<m>def</m></w><w type="erg">blah</w>
</expan>
</choice>
<choice>
<abbr>+def</abbr>
<expan>
<w>de<m>f</m></w>
</expan>
</choice>
</root>
====
Here is a stylesheet trying to solve that
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/2010/mf"
xmlns:functx="http://www.functx.com"
exclude-result-prefixes="xsd mf functx">
<xsl:function name="functx:escape-for-regex" as="xsd:string"
>
<xsl:param name="arg" as="xsd:string?"/>
<xsl:sequence select="
replace($arg,
'(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1')
"/>
</xsl:function>
<xsl:param name="abbr-url" as="xsd:string"
select="'test2010021902.xml'"/>
<xsl:variable name="abbr" as="element(abbr)*"
select="doc($abbr-url)/root/choice/abbr"/>
<xsl:function name="mf:replace" as="node()*">
<xsl:param name="str" as="xsd:string"/>
<xsl:param name="abbr" as="element(abbr)*"/>
<xsl:choose>
<xsl:when test="$abbr">
<xsl:analyze-string select="$str"
regex="{functx:escape-for-regex($abbr[1])}">
<xsl:matching-substring>
<xsl:copy-of select="$abbr[1]/../expan/w"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:sequence select="mf:replace(., $abbr[position() gt 1])"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="seg">
<xsl:copy>
<xsl:sequence select="mf:replace(., $abbr)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
--
Martin Honnen
http://msmvps.com/blogs/martin_honnen/
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--