On Fri, Feb 19, 2010 at 11:57, Martin Honnen
<Martin(_dot_)Honnen(_at_)gmx(_dot_)de> wrote:
Here is a stylesheet trying to solve that
Wow, that seems to do what I want! See comments inline where I try to
understand what is going on (so that when I google for this in a
couple years I can see what I thought was happening!). Thanks
Martin. (Someone off-list sent me a perl script that might accomplish
the same thing... but I'd prefer to do it in XSLT if possible ;-) )
For posterity:
<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>
Include the functx:escape-for-regex to escape the strings because I
intentionally made sure some of the strings in my sample had
regex-nasty characters like + and such (because my real input does).
<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"/>
Load nodeset of abbr elements as a variable from the lookuptable file
storing them as elements
Define the mf:replace function:
<xsl:function name="mf:replace" as="node()*">
<xsl:param name="str" as="xsd:string"/>
<xsl:param name="abbr" as="element(abbr)*"/>
which has two parameters a string and an abbr element
<xsl:choose>
<xsl:when test="$abbr">
<xsl:analyze-string select="$str"
regex="{functx:escape-for-regex($abbr[1])}">
analyze string provided looking for the first abbr (escaped for any regex)
<xsl:matching-substring>
<xsl:copy-of select="$abbr[1]/../expan/w"/>
</xsl:matching-substring>
when it matches, go up to parent and copy-of the content of expan/w
<xsl:non-matching-substring>
<xsl:sequence select="mf:replace(., $abbr[position() gt 1])"/>
</xsl:non-matching-substring>
when it doesn't match take the next thing in the implicit sequence
inside the abbr recursively calling mf:replace()
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
If there isn't $abbr then put our the string.
</xsl:choose>
</xsl:function>
standard copy-all template:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
Everytime you come across a seg kick this off by copying it and for
its contents making a sequence of mf:replace()
<xsl:template match="seg">
<xsl:copy>
<xsl:sequence select="mf:replace(., $abbr)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Thanks Martin!
-James
--~------------------------------------------------------------------
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>
--~--