xsl-list
[Top] [All Lists]

recursive string replace with tags

2003-07-02 11:33:56
Hi, thanks for the previous help, maybe a hint again cause I didn't find my
way out of it yet ...

*The goal:*
I'm inserting a <a> tag in my source document around each occurence of words
mentioned in a dictionary (mygloss.xml).

*The Problem:*
while recursing through the dictionnary list of words, the tags inserted
arounds preceding words disappear because of the variable and substring
calls.

*The solution By David Carlisle*
 you want to do is restructure your replacement as follows.
- do the first word by applying these templates, storing the entire result
of the replacement into a variable,
- then use your processors node-set() extension function to convert this
variable back to a node set,
- then apply the templates again, this time looking for your second word
- etc until you run out of words.

*The failure:*
Unfortunately, I really didn't get this idea to work.
If I "apply-templates" I can't send the position param.
And call-template xith xalan:nodeset($addlinks) gives a :
XSLT error: Cannot create item in result tree:  (, line -1, column -1)

________CODE_______

**mygloss.xml**
<?xml version="1.0" ?>
<dic>
  <item>
        <mot>string</mot>
        <trans>chaine</trans></item>
  <item>
        <mot>tag</mot>
        <trans>balise</trans></item>
  <item>
        <mot>duplicate</mot>
        <trans>doublon</trans></item>
</dic>


**mydoc.xml***
<?xml version="1.0" encoding="iso-8859-1"?>
<doc>
This is a test on how to manipulate a string inside a tag language.
</doc>

**output_expexted**
<?xml version="1.0" encoding="iso-8859-1"?>
<doc>
This is a test on how to manipulate a TEST1<a href="chaine">string</a>TEST2
inside a TEST1<a href="balise">tag</a>TEST2 language.
</doc>

**output_obtained**
<?xml version="1.0" encoding="iso-8859-1"?>
<doc>
This is a test on how to manipulate a TEST1stringTEST2 inside a TEST1<a
href="balise">tag</a>TEST2 language.
</doc>

_________________
The presence of the "TEST" around the word "string" proves that the
recursion worked but  the <a> are removed and can only be found around the
word "tag".
____________________


**mystyle.xsl**
<?xml version="1.0" ?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0" xmlns:xalan="http://xml.apache.org/xalan";
                   exclude-result-prefixes="xalan">
   <xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>


<xsl:template match="/">
<html>
 <head>
   <link rel="stylesheet" type="text/css"
href="http://localhost:8080/exist/cibapp/docs/css1.css"/>
 </head>
 <body>
  <xsl:apply-templates/>
 </body>
</html>
</xsl:template>


<xsl:template match="node()">
<xsl:copy>
 <xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- http://www.dpawson.co.uk/xsl/sect2/StringReplace.html -->


<!-- Gets text nodes and send them to "gloss" template for treatment -->
<xsl:template match="text()">
  <xsl:variable name="replaced_text">
    <xsl:call-template name="gloss">
 <xsl:with-param name="input_text" select="."/>
    </xsl:call-template>
  </xsl:variable>
    <xsl:copy-of select="$replaced_text" />
</xsl:template>


<xsl:template name="gloss">
<!-- takes the first word in dictionnary and sends the text nodes
to "links" for treatment-->
<xsl:param name="input_text"/>
<xsl:param name="pos" select="1"/>
<xsl:variable name="word" select="(document('mongloss.xml')//mot)[$pos]"/>
 <xsl:variable name="addlinks">
     <xsl:call-template name="links">
  <xsl:with-param name="input_text" select="$input_text"/>
  <xsl:with-param name="word" select="$word"/>
  <xsl:with-param name="pos" select="$pos" />
     </xsl:call-template>
 </xsl:variable>
<!--Calls the same template with next word of the dictionnary
if there is one-->
<xsl:choose>
<xsl:when test="$pos &lt; count(document('mongloss.xml')//mot)">
 <xsl:call-template name="gloss">
  <xsl:with-param name="input_text"><xsl:copy-of
select="$addlinks"/></xsl:with-param>
  <xsl:with-param name="pos" select="$pos + 1" />
 </xsl:call-template>
</xsl:when>
 <xsl:otherwise>
  <xsl:copy-of select="$addlinks"/>
 </xsl:otherwise>
</xsl:choose>
</xsl:template>


<!-- Parses the text node checking for the dictionnary word.
Adds a <a> element around the word in the string.-->
<xsl:template name="links">
    <xsl:param name="input_text"/>
    <xsl:param name="word"/>
    <xsl:param name="pos"/>
  <xsl:choose>
    <xsl:when test="contains($input_text, $word)">
 <xsl:copy-of select="substring-before($input_text, $word)"/>
TEST1<xsl:element name="a">
  <xsl:attribute name="href">
         <xsl:value-of
select="(document('mongloss.xml')//mot)[$pos]/following-sibling::trans"/>
  </xsl:attribute>
  <xsl:value-of select="$word"/>
 </xsl:element>TEST2 <xsl:call-template name="links">
  <xsl:with-param name="input_text" select="substring-after($input_text,
$word)"/>
   <xsl:with-param name="word" select="$word"/>
 </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
 <xsl:copy-of select="$input_text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

___________ END CODE _______

I've spent most of my time on this but still can't find the proper templates
architecture for it.
Hope someone can put me on the track (I've send the full code).

François
fxp.xsl(a)laposte.net


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>