RE: [xsl] Highlighting words/phrases
2006-07-28 15:17:10
OK, I see now what you were trying to achieve. Not a problem I would relish
tackling in XSLT 1.0.
Michael Kay
http://www.saxonica.com/
-----Original Message-----
From: yguaba(_at_)yahoo(_dot_)com(_dot_)br
[mailto:yguaba(_at_)yahoo(_dot_)com(_dot_)br]
Sent: 28 July 2006 18:00
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Highlighting words/phrases
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! esta 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>
--~--
--~------------------------------------------------------------------
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>
--~--
|
|