RE: [xsl] Multiple String Replacements [with a twist]

Subject: RE: [xsl] Multiple String Replacements [with a twist]
From: "Ignacio Garcia del Campo" <igarc001@xxxxxxxxxxx>
Date: Wed, 28 Mar 2007 11:32:14 -0400
One more question regarding this...

The output finally looks good on a browser, with the substitutions holding the links, but if I look at the source code for the html generated, the XSLT processor sticks "<link>" in front of all the substitutions.

I guess that is because the copy-of statement copies the whole element which is:
<link><a href.....>text</a></link>


but then I don't undestrand why the ending tag </link> is not included also.

I tried using analyze-string once again to remove the <link> text right before outputing, but then the link references are lost again...


From: "Ignacio Garcia del Campo" <igarc001@xxxxxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] Multiple String Replacements [with a twist]
Date: Wed, 28 Mar 2007 09:41:48 -0400

Everything works in XSLT 2.0 by using the analyze-string function.

Thanks for the pointers Mike and David
IGC


From: "Ignacio Garcia del Campo" <igarc001@xxxxxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] Multiple String Replacements [with a twist]
Date: Wed, 28 Mar 2007 09:20:26 -0400

XSLT 2.0 will also be acceptable if it is easier and faster.
I guess that using some tool to process XSLT 2.0 before presenting the output wouldn't be the worst case.


I included before all the code I had using XSLT 1.0 .

Thanks


From: "Ignacio Garcia del Campo" <igarc001@xxxxxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: RE: [xsl] Multiple String Replacements [with a twist]
Date: Wed, 28 Mar 2007 08:35:26 -0400

I would like to use XSLT 1.0 if possible, since the idea is that IE will get the xml file and parse the output.

Here is my code (this is just a short example I created to make sure that what I wanted was possible to do, before I applied it to my real files, but if it works here I can translate it)

XSLT FILE:
---------------
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
<!-- reusable replace-string function -->


<xsl:template name="replace-string">
   <xsl:param name="text"/>
   <xsl:param name="from"/>
   <xsl:param name="to"/>

   <xsl:choose>
		<xsl:when test="contains($text, $from)">
			<xsl:variable name="before" select="substring-before($text, $from)"/>
			<xsl:variable name="after" select="substring-after($text, $from)"/>
			<xsl:variable name="prefix" select="concat($before, $to)"/>
			<xsl:copy-of select="$before"/>
			<xsl:copy-of select="$to"/>
			<xsl:call-template name="replace-string">
			  <xsl:with-param name="text" select="$after"/>
			  <xsl:with-param name="from" select="$from"/>
			  <xsl:with-param name="to" select="$to"/>
			</xsl:call-template>
		</xsl:when>
		<xsl:otherwise>
			<xsl:copy-of select="$text"/>
		</xsl:otherwise>
   </xsl:choose>

</xsl:template>


<xsl:template name="replace-strings"> <xsl:param name="text" /> <xsl:param name="changes" /> <xsl:param name="count" />

	<xsl:param name="returnString">
		<xsl:call-template name="replace-string">
			<xsl:with-param name="text" select="$text"/>
			<xsl:with-param name="from" select="$changes/change[$count]/text" />
			<xsl:with-param name="to" select="$changes/change[$count]/link" />
		</xsl:call-template>
	</xsl:param>

	<xsl:if test="$count > 1">
		<xsl:call-template name="replace-strings">
			<xsl:with-param name="text">
				<xsl:copy-of select="$returnString" />
			</xsl:with-param>
			<xsl:with-param name="changes" select="$changes" />
			<xsl:with-param name="count" select="$count - 1" />
		</xsl:call-template>
   </xsl:if>

	<xsl:if test="$count = 1">
		<xsl:copy-of select="$returnString" />
	</xsl:if>
</xsl:template>


<!-- test the function -->


<xsl:template match="/">
 <html>
 <body>
 <h2>My Collection</h2>
   <table border="1">
     <tr bgcolor="#9acd32">
       <th align="left">Title</th>
       <th align="left">Artist</th>
		<th align="left">Change#</th>
     </tr>
     <xsl:for-each select="catalog/cd">
     <tr>
       <td>
			<xsl:choose>
				<xsl:when test="count(changes/change) > 0">
					<xsl:call-template name="replace-strings">
			        <xsl:with-param name="text"
			             select="title"/>
			        <xsl:with-param name="changes" select="changes"/>
					<xsl:with-param name="count" select="count(changes/change)" />
					</xsl:call-template>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="title" />
				</xsl:otherwise>
			</xsl:choose>
		</td>
       <td><xsl:value-of select="artist"/></td>
		<td>
			<xsl:value-of select="count(changes/change)" />
		</td>
     </tr>
     </xsl:for-each>
   </table>
 </body>
 </html>
</xsl:template>

<xsl:template match="NewTemplate">

</xsl:template>
</xsl:stylesheet>
-------------------------------------

XML FILE:
--------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog_test.xsl" ?>
<catalog>
	<cd>
		<title>The [[Fire]] of [[Athens]]</title>
		<artist>John Lewis</artist>
		<country>USA</country>
		<company>Columbia</company>
		<price>10.90</price>
		<year>1985</year>
		<changes>
			<change>
				<text>[[Fire]]</text>
				<link><a href="http://en.wikipedia.org/wiki/Fire";>Fire</a></link>
			</change>
			<change>
				<text>[[Athens]</text>
				<link><a href="http://en.wikipedia.org/wiki/Athens";>Athens</a></link>
			</change>
		</changes>
	</cd>
	<cd>
		<title>Hide your heart</title>
		<artist>Bonnie Tyler</artist>
		<country>UK</country>
		<company>CBS Records</company>
		<price>9.90</price>
		<year>1988</year>
		<changes/>
	</cd>
	<cd>
		<title>Greatest Hits</title>
		<artist>Dolly Parton</artist>
		<country>USA</country>
		<company>RCA</company>
		<price>9.90</price>
		<year>1982</year>
		<changes/>
	</cd>
</catalog>
-------------------------------------------------

I placed the [[ ]] around the words I want replaced, because in my actual files there are instances that have to be replaced and others that don't, so I will add some kind of character code to differenciate them.

Thank you.

From: "Michael Kay" <mike@xxxxxxxxxxxx>
Reply-To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: RE: [xsl] Multiple String Replacements [with a twist]
Date: Wed, 28 Mar 2007 00:13:25 +0100

If you can use XSLT 2.0, then xsl:analyze-string is the perfect answer to
this problem.


It's possible but tedious to do it with XSLT 1.0 using recursive templates.
It's difficult to tell you what you're doing wrong since you haven't shown
us your code.


Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Ignacio Garcia del Campo [mailto:igarc001@xxxxxxxxxxx]
> Sent: 27 March 2007 19:56
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Multiple String Replacements [with a twist]
>
> Hello all,
>
> I just started working with XSLT and I find my self stuck on
> this issue.
>
> I want to replace multiple strings for some for most of my
> elements and by looking at some discussions and some code by
> Jeni Tennison I can replace all instances of my strings by a
> simple replacement. However, what I actually want to do, is
> to replace the strings by links.
>
> My replacements look like this:
>
> <foo:string_replacements>
>
>   <foo:search>
>
>      <foo:find>XML</foo:find>
>
>      <foo:replace><a href="xml.com">XML-SITE</a></foo:replace>
>
>   </foo:search>
>
> </foo:string_replacements>
>
> If I use <xlst:copy-of select="foo:search[xx]/replace" /> the
> HTML shows the link correctly, but since I am doing multiple
> substitions of multiple strings I use recursion, and the
> function where the strings are exchanged fails to correctly
> place the anchor code on the output.
>
> I get XML replaced by XML-SITE but the anchor information is
> lost in the process.
>
> I have tried using CDATA sections, but then as you might
> expect I get the escaped string and that's not good either.
>
> Does anyone know how to solve this problem?
>
> I have been using something similar to this:
> http://sources.redhat.com/ml/xsl-list/2000-06/msg00200.html,
> but I need the links to be working.
>
>
>
> Thanks.

Current Thread