On 27 Jul 2006 at 22:54:21, Michael Kay wrote:
If you change your code so that it makes a recursive call on "highlight"
in place of the call on "search-and-replace" (whose function is unclear
from your description), then it will highlight all the occurrences.
You're right, of course, Michael: I was adapting another template and
forgot to change the name in the recursion. It's always an honour to
get a reply from you, but that wasn't really the issue.
My problem was that the template only highlighted the first word or
phrase from the list (i.e. the first "keyword" element), whereas what
I needed was something that would iterate through *all* the keyword
elements, check whether their text was present in the "contents"
element, and, if so, enclose the matching bit as in this example:
<span class="highlight">matching bit</span>.
I ended up figuring out that a for-each loop wouldn't work, as it
would keep concatenating the same bits of the input string that had
already been checked for the presence of the previous key word. In
the end I concluded that the only viable solution would be to
recurse.
After much testing and tweaking, I got the little monster below to do
what I need. If anyone has any suggestions on ways to simplify and/or
optimize this template, it would be great to hear them.
Cheers,
Erik
------------------------
T E M P L A T E
------------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform
http://www.w3.org/2004/11/schema-for-xslt20.xsd">
<xsl:output method="html" indent="yes" encoding="utf-8"/>
<xsl:variable name="lower-case"
select="'abcdefg�
68;ijklmnop&#x
0071;rstuvwxy&
#x007A;µàáâãäåæ
;çèéêëìíî�
EF;ðñòóôõöø&#x
00F9;úûüýþÿāă&
#x0105;ćĉċčďđēĕ
;ėęěĝğġģĥ
27;ĩīĭįıijĵķ&#x
013A;ļľŀłńņňŋ&
#x014D;ŏőœŕŗřśŝ
;şšţťŧũūŭ
6F;űųŵŷźżžſ&#x
0183;ƅƈƌƒƕƙơƣ&
#x01A5;ƨƭưƴƶƹƽƿ
;DždžLjljNjnjǎǐ
D2;ǔǖǘǚǜǝǟǡ&#x
01E3;ǥǧǩǫǭǯDzdz&
#x01F5;ǹǻǽǿȁȃȅȇ
;ȉȋȍȏȑȓȕȗ
19;țȝȟȣȥȧȩȫ&#x
022D;ȯȱȳɓɔɖɗə&
#x025B;ɠɣɨɩɯɲɵʀ
;ʃʈʊʋʒͅάέ
AE;ίαβγδεζη&#x
03B8;ικλμνξοπ&
#x03C1;ςστυφχψω
;ϊϋόύώϐϑϕ
D6;ϛϝϟϡϣϥϧϩ&#x
03EB;ϭϯϰϱϲϵаб&
#x0432;гдежзийк
;лмнопрст
43;фхцчшщъы&#x
044C;эюяѐёђѓє&
#x0455;іїјљњћќѝ
;ўџѡѣѥѧѩѫ
6D;ѯѱѳѵѷѹѻѽ&#x
047F;ҁҍҏґғҕҗҙ&
#x049B;ҝҟҡңҥҧҩҫ
;ҭүұҳҵҷҹһ
BD;ҿӂӄӈӌӑӓӕ&#x
04D7;әӛӝӟӡӣӥӧ&
#x04E9;ӫӭӯӱӳӵӹա
;բգդեզէըթ
6A;իլխծկհձղ&#x
0573;մյնշոչպջ&
#x057C;սվտրցւփք
;օֆḁḃḅḇḉḋ
0D;ḏḑḓḕḗḙḛḝ&#x
1E1F;ḡḣḥḧḩḫḭḯ&
#x1E31;ḳḵḷḹḻḽḿṁ
;ṃṅṇṉṋṍṏṑ
53;ṕṗṙṛṝṟṡṣ&#x
1E65;ṧṩṫṭṯṱṳṵ&
#x1E77;ṹṻṽṿẁẃẅẇ
;ẉẋẍẏẑẓẕẛ
A1;ảấầẩẫậắằ&#x
1EB3;ẵặẹẻẽếềể&
#x1EC5;ệỉịọỏốồổ
;ỗộớờởỡợụ
E7;ứừửữựỳỵỷ&#x
1EF9;ἀἁἂἃἄἅἆἇ&
#x1F10;ἑἒἓἔἕἠἡἢ
;ἣἤἥἦἧἰἱἲ
33;ἴἵἶἷὀὁὂὃ&#x
1F44;ὅὑὓὕὗὠὡὢ&
#x1F63;ὤὥὦὧὰάὲέ
;ὴήὶίὸόὺύ
7C;ώᾀᾁᾂᾃᾄᾅᾆ&#x
1F87;ᾐᾑᾒᾓᾔᾕᾖᾗ&
#x1FA0;ᾡᾢᾣᾤᾥᾦᾧᾰ
;ᾱᾳιῃῐῑῠῡ
E5;ῳⅰⅱⅲⅳⅴⅵⅶ&#x
2177;ⅸⅹⅺⅻⅼⅽⅾⅿ&
#x24D0;ⓑⓒⓓⓔⓕⓖⓗⓘ
;ⓙⓚⓛⓜⓝⓞⓟⓠ$
E1;ⓢⓣⓤⓥⓦⓧⓨⓩ&#x
FF41;bcdefghi&
#xFF4A;klmnopqr
;stuvwxyz
428;𐐩𐐪𐐫𐐬𐐭𐐮𐐯&#x
10430;𐐱𐐲𐐳𐐴𐐵𐐶𐐷&
#x10438;𐐹𐐺𐐻𐐼𐐽𐐾𐐿
;𐑀𐑁𐑂𐑃𐑄𐑅𐑆Ą
47;𐑈𐑉𐑊𐑋𐑌𐑍'"/>
<xsl:variable name="upper-case"
select="'ABCDEFG�
48;IJKLMNOP&#x
0051;RSTUVWXY&
#x005A;ΜÀÁÂÃÄÅÆ
;ÇÈÉÊËÌÍÎ�
CF;ÐÑÒÓÔÕÖØ&#x
00D9;ÚÛÜÝÞŸĀĂ&
#x0104;ĆĈĊČĎĐĒĔ
;ĖĘĚĜĞĠĢĤ
26;ĨĪĬĮIIJĴĶ&#x
0139;ĻĽĿŁŃŅŇŊ&
#x014C;ŎŐŒŔŖŘŚŜ
;ŞŠŢŤŦŨŪŬ
6E;ŰŲŴŶŹŻŽS&#x
0182;ƄƇƋƑǶƘƠƢ&
#x01A4;ƧƬƯƳƵƸƼǷ
;DŽDŽLJLJNJNJǍǏ
D1;ǓǕǗǙǛƎǞǠ&#x
01E2;ǤǦǨǪǬǮDZDZ&
#x01F4;ǸǺǼǾȀȂȄȆ
;ȈȊȌȎȐȒȔȖ
18;ȚȜȞȢȤȦȨȪ&#x
022C;ȮȰȲƁƆƉƊƏ&
#x0190;ƓƔƗƖƜƝƟƦ
;ƩƮƱƲƷΙΆΈ
89;ΊΑΒΓΔΕΖΗ&#x
0398;ΙΚΛΜΝΞΟΠ&
#x03A1;ΣΣΤΥΦΧΨΩ
;ΪΫΌΎΏΒΘΦ
A0;ϚϜϞϠϢϤϦϨ&#x
03EA;ϬϮΚΡΣΕАБ&
#x0412;ГДЕЖЗИЙК
;ЛМНОПРСТ
23;ФХЦЧШЩЪЫ&#x
042C;ЭЮЯЀЁЂЃЄ&
#x0405;ІЇЈЉЊЋЌЍ
;ЎЏѠѢѤѦѨѪ
6C;ѮѰѲѴѶѸѺѼ&#x
047E;ҀҌҎҐҒҔҖҘ&
#x049A;ҜҞҠҢҤҦҨҪ
;ҬҮҰҲҴҶҸҺ
BC;ҾӁӃӇӋӐӒӔ&#x
04D6;ӘӚӜӞӠӢӤӦ&
#x04E8;ӪӬӮӰӲӴӸԱ
;ԲԳԴԵԶԷԸԹ
3A;ԻԼԽԾԿՀՁՂ&#x
0543;ՄՅՆՇՈՉՊՋ&
#x054C;ՍՎՏՐՑՒՓՔ
;ՕՖḀḂḄḆḈḊ
0C;ḎḐḒḔḖḘḚḜ&#x
1E1E;ḠḢḤḦḨḪḬḮ&
#x1E30;ḲḴḶḸḺḼḾṀ
;ṂṄṆṈṊṌṎṐ
52;ṔṖṘṚṜṞṠṢ&#x
1E64;ṦṨṪṬṮṰṲṴ&
#x1E76;ṸṺṼṾẀẂẄẆ
;ẈẊẌẎẐẒẔṠ
A0;ẢẤẦẨẪẬẮẰ&#x
1EB2;ẴẶẸẺẼẾỀỂ&
#x1EC4;ỆỈỊỌỎỐỒỔ
;ỖỘỚỜỞỠỢỤ
E6;ỨỪỬỮỰỲỴỶ&#x
1EF8;ἈἉἊἋἌἍἎἏ&
#x1F18;ἙἚἛἜἝἨἩἪ
;ἫἬἭἮἯἸἹἺ
3B;ἼἽἾἿὈὉὊὋ&#x
1F4C;ὍὙὛὝὟὨὩὪ&
#x1F6B;ὬὭὮὯᾺΆῈΈ
;ῊΉῚΊῸΌῪΎ
FA;Ώᾈᾉᾊᾋᾌᾍᾎ&#x
1F8F;ᾘᾙᾚᾛᾜᾝᾞᾟ&
#x1FA8;ᾩᾪᾫᾬᾭᾮᾯᾸ
;ᾹᾼΙῌῘῙῨῩ
EC;ῼⅠⅡⅢⅣⅤⅥⅦ&#x
2167;ⅨⅩⅪⅫⅬⅭⅮⅯ&
#x24B6;ⒷⒸⒹⒺⒻⒼⒽⒾ
;ⒿⓀⓁⓂⓃⓄⓅⓆ$
C7;ⓈⓉⓊⓋⓌⓍⓎⓏ&#x
FF21;BCDEFGHI&
#xFF2A;KLMNOPQR
;STUVWXYZ
400;𐐁𐐂𐐃𐐄𐐅𐐆𐐇&#x
10408;𐐉𐐊𐐋𐐌𐐍𐐎𐐏&
#x10410;𐐑𐐒𐐓𐐔𐐕𐐖𐐗
;𐐘𐐙𐐚𐐛𐐜𐐝𐐞Ą
1F;𐐠𐐡𐐢𐐣𐐤𐐥'"/>
<xsl:template name="highlight">
<xsl:param name="input"/>
<xsl:param name="target"/>
<xsl:param name="elem-name" select="'span'"/>
<xsl:param name="class-name"/>
<xsl:param name="caseless" select="true()"/>
<xsl:choose>
<xsl:when test="$caseless and $target[1]">
<xsl:choose>
<xsl:when
test="contains(translate($input, $upper-case, $lower-
case), translate($target[1], $upper-case, $lower-case))">
<xsl:call-template
name="highlight">
<xsl:with-param
name="input" select="substring( $input, 1,
string-length(substring-before(translate($input, $upper-case, $lower-
case), translate($target[1], $upper-case, $lower-case))) )"/>
<xsl:with-param
name="target" select="$target[position() >
1]"/>
<xsl:with-param
name="class-name" select="$class-name"/>
</xsl:call-template>
<xsl:element
name="{$elem-name}">
<xsl:attribute
name="class">
<xsl:value-of
select="$class-name"/>
</xsl:attribute>
<xsl:value-of
select="substring($input, string-
length(substring-before(translate($input, $upper-case, $lower-case),
translate($target[1], $upper-case, $lower-case))) + 1, string-
length($target[1]))"/>
</xsl:element>
<xsl:choose>
<xsl:when
test="contains(substring-after(translate($input,
$upper-case, $lower-case), translate($target[1], $upper-case, $lower-
case)), translate($target[1], $upper-case, $lower-case))">
<xsl:call-template name="highlight">
<xsl:with-param name="input" select="substring($input,
string-length(substring-before(translate($input, $upper-case, $lower-
case), translate($target[1], $upper-case, $lower-case))) + string-
length($target[1]) + 1)"/>
<xsl:with-param name="target" select="$target"/>
<xsl:with-param name="class-name" select="$class-name"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="highlight">
<xsl:with-param name="input" select="substring($input,
string-length(substring-before(translate($input, $upper-case, $lower-
case), translate($target[1], $upper-case, $lower-case))) + string-
length($target[1]) + 1)"/>
<xsl:with-param name="target" select="$target[position()
> 1]"/>
<xsl:with-param name="class-name" select="$class-name"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template
name="highlight">
<xsl:with-param
name="input" select="$input"/>
<xsl:with-param
name="target" select="$target[position() >
1]"/>
<xsl:with-param
name="class-name" select="$class-name"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="not($caseless) and $target[1]">
<xsl:choose>
<xsl:when test="contains($input,
$target[1])">
<xsl:call-template
name="highlight">
<xsl:with-param
name="input" select="substring-before($input,
$target[1])"/>
<xsl:with-param
name="target" select="$target[position() >
1]"/>
<xsl:with-param
name="class-name" select="$class-name"/>
<xsl:with-param
name="caseless" select="false()"/>
</xsl:call-template>
<xsl:element
name="{$elem-name}">
<xsl:attribute
name="class">
<xsl:value-of
select="$class-name"/>
</xsl:attribute>
<xsl:value-of
select="$target[1]"/>
</xsl:element>
<xsl:choose>
<xsl:when
test="contains(substring-after($input, $target[1]),
$target[1])">
<xsl:call-template name="highlight">
<xsl:with-param name="input" select="substring-after($input,
$target[1])"/>
<xsl:with-param name="target" select="$target"/>
<xsl:with-param name="class-name" select="$class-name"/>
<xsl:with-param name="caseless" select="false()"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="highlight">
<xsl:with-param name="input" select="substring-after($input,
$target[1])"/>
<xsl:with-param name="target" select="$target[position()
> 1]"/>
<xsl:with-param name="class-name" select="$class-name"/>
<xsl:with-param name="caseless" select="false()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template
name="highlight">
<xsl:with-param
name="input" select="$input"/>
<xsl:with-param
name="target" select="$target[position() >
1]"/>
<xsl:with-param
name="class-name" select="$class-name"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
_______________________________________________________
O Yahoo! está de cara nova. Venha conferir!
http://br.yahoo.com/preview
--~------------------------------------------------------------------
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>
--~--