Subject: Re: [xsl] recursive string replace with tags From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Wed, 2 Jul 2003 22:34:03 +0100 |
Hi François, Thanks for spelling out your problem so clearly. > *The goal:* > I'm inserting a <a> tag in my source document around each occurence > of words mentioned in a dictionary (mygloss.xml). OK, here goes. You need a recursive template that takes a string and a list of replacements: <xsl:template name="gloss"> <xsl:param name="string" /> <xsl:param name="gloss" select="document('mygloss.xml')/dic/item" /> ... </xsl:template> There are two stopping conditions that should cause the template to stop recursing: one is when $string is empty and one is when $gloss is empty. In either case, giving the value of $string gives you what you want: <xsl:template name="gloss"> <xsl:param name="string" /> <xsl:param name="gloss" select="document('mygloss.xml')/dic/item" /> <xsl:choose> <xsl:when test="$string and $gloss"> ... </xsl:when> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> The next test is to see if the first word in the glossary appears in the string: <xsl:template name="gloss"> <xsl:param name="string" /> <xsl:param name="gloss" select="document('mygloss.xml')/dic/item" /> <xsl:choose> <xsl:when test="$string and $gloss"> <xsl:choose> <xsl:when test="contains($string, $gloss[1]/mot)"> ... </xsl:when> <xsl:otherwise> ... </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> If the string doesn't contain the first word in the glossary, then the result needs to be the result of calling the template on the string with the rest of the words in the glossary: <xsl:template name="gloss"> <xsl:param name="string" /> <xsl:param name="gloss" select="document('mygloss.xml')/dic/item" /> <xsl:choose> <xsl:when test="$string and $gloss"> <xsl:choose> <xsl:when test="contains($string, $gloss[1]/mot)"> ... </xsl:when> <xsl:otherwise> <xsl:call-template name="gloss"> <xsl:with-param name="string" select="$string" /> <xsl:with-param name="gloss" select="$gloss[position() > 1]" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> If the string does contain the first word, then you need to do three things: 1. Process the string before the first word to see if it contains any of the remaining words in the glossary. 2. Create an <a> element around the word to link to the translation. 3. Process the string after the first word to see if it contains the word again. Thus the completed template is: <xsl:template name="gloss"> <xsl:param name="string" /> <xsl:param name="gloss" select="document('mygloss.xml')/dic/item" /> <xsl:choose> <xsl:when test="$string and $gloss"> <xsl:choose> <xsl:when test="contains($string, $gloss[1]/mot)"> <xsl:variable name="mot" select="$gloss[1]/mot" /> <xsl:call-template name="gloss"> <xsl:with-param name="string" select="substring-before($string, $mot)" /> <xsl:with-param name="gloss" select="$gloss[position() > 1]" /> </xsl:call-template> <a href="{$gloss[1]/trans}"> <xsl:value-of select="$mot" /> </a> <xsl:call-template name="gloss"> <xsl:with-param name="string" select="substring-after($string, $mot)" /> <xsl:with-param name="gloss" select="$gloss" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="gloss"> <xsl:with-param name="string" select="$string" /> <xsl:with-param name="gloss" select="$gloss[position() > 1]" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$string" /> </xsl:otherwise> </xsl:choose> </xsl:template> To invoke the stylesheet use something like: <xsl:template match="doc"> <xsl:call-template name="gloss"> <xsl:with-param name="string" select="string(.)" /> </xsl:call-template> </xsl:template> I hope that gets you on the right track. Let us know if anything is unclear. Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] recursive string replace with, François Parlant | Thread | Re: [xsl] recursive string replace , François Parlant |
Re: [xsl] passing parameter to temp, Rick Taylor | Date | [xsl] Moving an attribute from a no, Kevin Tracey |
Month |