[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] recursive replacing strings with nodes


Subject: [xsl] recursive replacing strings with nodes
From: James Cummings <james+xsl@xxxxxxxxxxxxxxxxx>
Date: Fri, 19 Feb 2010 11:05:09 +0000

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>
 ====

But of course, the reason my replace() solution is failing is that I
want to replace the strings in <seg> with richer markup, not just
output strings. Each time I come across the content of an <abbr> in
the current <seg> (which should have no internal markup) I want to
replace it with a copy-of the content of the <expan>, but continue to
process the <seg> in case there are other matches that I've missed.

If I've done my eyeballed replacements correctly the following should
be the output:

====
    <root>
        <ab type="foo">
            <seg><w>ab<m>c</m></w> def
<w>ab<m>c</m></w><w>de<m>f</m></w></seg><lb/>
            <seg><w>de<m>f</m></w> <w>ab<m>c</m></w>def
<w>foo<m>def</m></w><w type="erg">blah</w></seg><lb/>
            <seg><w>foo<m>def</m></w><w type="erg">blah</w></seg>
        </ab>
        <ab type="foo">
            <seg>ab de ac<w>de<m>f</m></w></seg><lb/>
            <seg>+cdef abdef <w>foo<m>def</m></w><w
type="erg">blah</w></seg><lb/>
            <seg>foo+cdef=blah</seg>
        </ab>
   </root>
====

Any suggestions? I'm sure I'm not the first person to do this, but
googling and trawling the archives turned up similar but significantly
different problems.

-James


Current Thread