Hi Michael,
I actually devised a way so that i would not always
process the whole 14000 list of strings in each pass
of the function so that i will not create a stack
overflow. what i did was i would place in another
variable the strings in the $WordList that are
contained in the text() node being processed and so
far its working :D.
<xsl:template match="text()[name(parent::*)!=$Tag]">
<xsl:variable name="x" as="xs:string" select="."/>
<xsl:variable name="srchStr" as="xs:string*">
<xsl:for-each select="$wordLst">
<xsl:if test="contains($x,.)">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="repLst" as="xs:string*"
select="for $i in (1 to count($srchStr)) return
f:tempReplacement($i)"/>
<xsl:variable name="tmpStr"
select="f:replace-all(.,$srchStr,$repLst,1)"/>
<xsl:value-of
select="f:replace-all($tmpStr,$repLst,$srchStr,0)"/>
</xsl:template>
thanks,
UlyLee
--- Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:
Hi! the listEXP.txt i have included here is just a
part of the actual listEXP.txt; on the original
list
there are 1400 strings. what i have listed below
consist only 9 strings. i tested the xsl again
using
the list of 9 strings and it was ok. so i think
the
error comes in when the list is too big for the
processor... am i correct at this??? if so how can
i
correct my xsl so that i can handle a list file
with
many strings???
Yes, I was coming to the same conclusion. Your code
appears to be
essentially correct but has run out of stack space.
Saxon should be able to
handle this with a technique called tail call
optimization - your recursive
call is the last thing the function does, so the
optimizer should turn it
into a loop. It's not clear to me at first sight why
this isn't happening.
If you can send me the required files I'll take a
look at it, though it may
not be for a few days.
Michael Kay
http://www.saxonica.com/
--UlyLee
--- UlyLee <ulyleeka(_at_)yahoo(_dot_)com> wrote:
I'm running an xsl transformation using saxon
8.6
and
i encounter this error, 'too many apply-template
calls'. The purpose of the xslt is to tag all
strings
in the listEXP.txt file with EXP. I have 2
templates
to match, 1st the template that matches * which
simply
copies the element and its attributes. the 2nd
is a
template that matches
text()[name(parent::*)!='EXP'],
here it should search all the occurrences of the
strings and tag it with EXP.
I have created two functions, 1 is the
tmpReplacement
function which creates a tree of strings that i
will
use as temporary replacement strings. and the
other
is
the replace-all function that do the search and
replace function.
the error message points me to the
apply-templates
in
the template that matches * but i think thats
not
the
one actually causing the error because when i
remove
the elements that calls the replace-all function
the
transformation is a success.
so i think the error is in the replace-all
function
but i can't seem to find out which part of the
function is actually causing it.
this is the xsl file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="data:,f">
<xsl:output method="xml" version="1.0"
encoding="utf-8" indent="yes"/>
<xsl:variable name="wordLst" as="xs:string*">
<xsl:analyze-string
select="unparsed-text('listEXP.txt','utf-8')"
regex="[\r\n]">
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template
match="text()[name(parent::*)!='EXP']">
<xsl:variable name="repLst" as="xs:string*"
select="for $i in (1 to count($wordLst)) return
f:tempReplacement($i)"/>
<xsl:variable name="tmpStr"
select="f:replace-all(.,$wordLst,$repLst,1)"/>
<xsl:value-of
select="f:replace-all($tmpStr,$repLst,$wordLst,0)"/>
</xsl:template>
<!--Function that creates a tree node of
temporary
replacement strings.-->
<xsl:function name="f:tempReplacement"
as="xs:string">
<xsl:param name="value" as="xs:integer"/>
<xsl:value-of select="if ($value < 10) then
concat('replacement','00',$value) else if
($value
>
9 and $value < 100) then
concat('replacement','0',$value) else
concat('replacement',$value)"/>
</xsl:function>
<!--Function that simulates a replace-all
function
and
returns the replaced string.-->
<xsl:function name="f:replace-all">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="words-to-replace"
as="xs:string*"/>
<xsl:param name="replacement" as="xs:string*"/>
<xsl:param name="flag" as="xs:integer"/>
<xsl:choose>
<xsl:when test="$flag=1">
<xsl:sequence select="if
(exists($words-to-replace))
then f:replace-all(replace($input,
replace($words-to-replace[1],
'[.\\?*+{}()\[\]^$]',
'\\$0'),
$replacement[1],'i'),remove($words-to-replace,1),remove($repla
cement,1),1)
else $input"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="if
(exists($words-to-replace))
then f:replace-all(replace($input,
replace($words-to-replace[1],
'[.\\?*+{}()\[\]^$]',
'\\$0'),
concat('<EXP>',$replacement[1],'</EXP>')),remove($words-to-rep
lace,1),remove($replacement,1),0)
else $input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
this is the listEXP.txt
Faire-part
Par-dessus
S. Prieure
dernier-né
sang-froid
sage-femme
Brise-bise
branle-bas
à peu près
here is the source xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<CORPUS>
<T1>
<LIB>
<T>1901-1913</T>trois cent soixante-cinq
chambres à coucher
<EXP>Faire-part</EXP>
Faire-part
sage-femme
Brise-bise
branle-bas
à peu près
</LIB>
</T1>
</CORPUS>
=== message truncated ===
__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005
http://mail.yahoo.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>
--~--