Preserve HTML tag when doing search and replace in XSLT

csaladores's Avatar

csaladores

15 Nov, 2010 05:18 PM

Hi All, is there a way to preserve html tags when doing search and replace in XSLT?

This is my xml:

<?xml version="1.0" encoding="utf-8" ?>
<system-data-structure>
  <content>
    Embattled New York Democratic because he hasn't been <a href="http://www.google.com">given</a> enough time to set up a defense fund to pay for legal representation.
  </content>
</system-data-structure>

This is my xslt;

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="apos">'</xsl:variable>
<xsl:variable name="escapos">&#8217;</xsl:variable>
<xsl:template match="system-data-structure">
  <xsl:call-template name="replace-string">
    <xsl:with-param name="text" select="content/node()"/>
    <xsl:with-param name="from" select="$apos"/>
    <xsl:with-param name="to" select="$escapos"/>
  </xsl:call-template>
</xsl:template>

  <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:stylesheet>

The result is:

<?xml version="1.0" encoding="utf-8"?>
    Embattled New York Democratic because he hasn't been

Basically, it cuts off after "been". The issue is that it cuts off when an html tag is recognized.

Any thoughts?
Thanks.

Christian

  1. 1 Posted by PatrickMc on 25 Nov, 2010 05:08 PM

    PatrickMc's Avatar

    Use biterscripting for things like this. To replace single quote with & # 3 9 in file C:/Web Server/Pages/Default/Response.xml, use commands like these

    var string xml

    Read file contents into a string variable.

    cat "C:/Web Server/Pages/Default/Response.xml" > $xml

    Repeatedly replace quote with & # 3 9.

    while ( { sen "^'^" $xml } > 0 )

    sal "^'^" "&#39" $xml > null
    

    Write content back to file.

    echo $xml > "C:/Web Server/Pages/Default/Response.xml"

    Done.

    Check the help pages for sen (string enumerator) and sal (string alterer) commands at http://www.biterscripting.com/helppages/sen.html and http://www.biterscripting.com/helppages/sal.html . You can do more complex replaces with them regular expressions, etc.

    You can write several layers of script to replace multiple strings, in multiple files, etc.

  2. 2 Posted by PatrickMc on 25 Nov, 2010 05:13 PM

    PatrickMc's Avatar

    That code got clobbered. Here is is again.

    Use biterscripting for things like this. To replace single quote with & # 3 9 in file C:/Web Server/Pages/Default/Response.xml, use commands like these

    var string xml
    # Read file contents into a string variable.
    cat "C:/Web Server/Pages/Default/Response.xml" > $xml
    # Repeatedly replace quote with & # 3 9.
    while ( { sen "^'^" $xml } > 0 )
        sal "^'^" "&#39" $xml > null
    # Write content back to file.
    echo $xml > "C:/Web Server/Pages/Default/Response.xml"
    # Done.
    

    Check the help pages for sen (string enumerator) and sal (string alterer) commands at http://www.biterscripting.com/helppages/sen.html and http://www.biterscripting.com/helppages/sal.html . You can do more complex replaces with them regular expressions, etc.

    You can write several layers of script to replace multiple strings, in multiple files, etc.

  3. 3 Posted by csaladores on 29 Nov, 2010 04:03 PM

    csaladores's Avatar

    Thanks for your input Patrick. Can this be done in the CMS?

  4. 4 Posted by Ross on 04 Mar, 2011 05:14 PM

    Ross's Avatar

    Hi, sorry for the long delay in any reply. The forums can get pretty busy sometimes. The problem with your search and replace template is that the string functions substring-before, substring-after, and concat all convert their parameters to a string just like xsl:value-of. This means that any elements will be stripped out.

    To preserve the elements while replacing parts of the text nodes within them, you'll need to be a bit more complex. Here's a revised <xsl:template match="system-data-structure"> plus a few more templates (the same <xsl:template name="replace-string"> is assumed):

    <xsl:template match="system-data-structure">
       <xsl:apply-templates select="content/node()" mode="replace"/>
    </xsl:template>
    
    <xsl:template match="@*|node()" mode="replace">
       <!-- Copy attributes and elements without changing them -->
       <xsl:copy>
          <xsl:apply-templates select="@*|node()" mode="replace"/>
       </xsl:copy>
    </xsl:template>
    
    <xsl:template match="text()" mode="replace">
        <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="."/>
          <xsl:with-param name="from" select="$apos"/>
          <xsl:with-param name="to" select="$escapos"/>
        </xsl:call-template>
    </xsl:template>
    
  5. Tim closed this discussion on 21 Jun, 2011 03:36 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac