[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: Multiple String Replacements [with a twist]

Subject: RE: Multiple String Replacements [with a twist]
From: "Ignacio Garcia del Campo" <igarc001@xxxxxxxxxxx>
Date: Wed, 28 Mar 2007 09:20:26 -0400
RE:  Multiple String Replacements [with a twist]
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:  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:  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:  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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.