[xsl] xml to xml using look-up-table

Subject: [xsl] xml to xml using look-up-table
From: "J. S. Rawat" <jrawat@xxxxxxxxxxxxxx>
Date: Fri, 21 Nov 2008 12:44:21 +0530
Hi list
I want to use some function (xml to xml and search and replace) written XSLT cookbook. In that examples we can replace attributes and elements by look up tables. In the same way I want to use search and replace within text. My text is getting repeat without any replacement but if I comment '<ren:text from="two" to="2"/>' within TableDriven.xslt, it is working fine. It is simply a matter of logic. Please help!!!
commandline is : $java -jar saxon8.jar input.xml tabledrive.xslt >out.xml


input.xml
<people which="MeAndMyFriends">
     <person firstname="Sal" lastname="Mangano">Person one</person>
     <person firstname="Sal" lastname="Mangano">Person one</person>
     <person firstname="Mike" lastname="Palmieri">Person two</person>
     <person firstname="Vito" lastname="Palmieri">Person three</person>
     <person firstname="Vinny" lastname="Mari">Person four</person>
</people>

copy.xslt
<xsl:stylesheet version="1.0"
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:template match="node(  ) | @*">
   <xsl:copy>
     <xsl:apply-templates select="@* | node(  )"/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

TableDriven.xslt
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:ren="http://www.ora.com/namespaces/rename";>
<xsl:import href="TableDrivenRename.xslt"/>
<!-- Load the lookup table. We define it locally but it can also come from an external file -->
<xsl:variable name="lookup" select="document('')/*[ren:*]"/>
<!-- Define the renaming rules -->
<ren:attribute from="firstname" to="givenname"/>
<ren:attribute from="lastname" to="surname"/>
<ren:text from="one" to="1"/>
<ren:text from="two" to="2"/>
</xsl:stylesheet>


TableDrivenRename.xslt
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:ren="http://www.ora.com/namespaces/rename";>

<xsl:import href="copy.xslt"/>
<!--Override in importing stylesheet -->
<xsl:variable name="lookup"  select="/.."/>

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

 <xsl:template match="@*">
  <xsl:choose>
   <xsl:when test="$lookup/ren:attribute[@from=name(current())]">
    <xsl:attribute name="{$lookup/ren:attribute[@from=name(current())]/@to}">
      <xsl:value-of select="."/>
    </xsl:attribute>
   </xsl:when>
   <xsl:otherwise>
     <xsl:apply-imports/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

 <xsl:template match="text()">
<xsl:variable name="input"  select="."/>
   <xsl:for-each select="$lookup/ren:text">
     <xsl:variable name="search-string">
      <xsl:value-of select="$lookup/ren:text/@from"/>
     </xsl:variable>
     <xsl:variable name="replace-string">
      <xsl:value-of select="$lookup/ren:text/@to"/>
     </xsl:variable>
     <xsl:call-template name="search-and-replace">
      <xsl:with-param name="input" select="$input"/>
      <xsl:with-param name="search-string" select="$search-string"/>
     <xsl:with-param name="replace-string" select="$replace-string"/>
    </xsl:call-template>
   </xsl:for-each>
 </xsl:template>

<xsl:template name="search-and-replace">
<xsl:param name="input"/>
<xsl:param name="search-string"/>
<xsl:param name="replace-string"/>
<xsl:choose>
<!-- See if the input contains the search string -->
<xsl:when test="$search-string and contains($input,$search-string)">
<!-- If so, then concatenate the substring before the search
string to the replacement string and to the result of
recursively applying this template to the remaining substring.-->
<xsl:value-of select="substring-before($input,$search-string)"/>
<xsl:value-of select="$replace-string"/>
<xsl:call-template name="search-and-replace">
<xsl:with-param name="input" select="substring-after($input,$search-string)"/>
<xsl:with-param name="search-string" select="$search-string"/>
<xsl:with-param name="replace-string" select="$replace-string"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- There are no more occurences of the search string so
just return the current input string -->
<xsl:value-of select="$input"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>


Thanks
...JSR


Current Thread