Replace String

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Hvid Hat

    Replace String

    Hi

    I want to highlight (make it bold) a word in some text I'm getting in XML
    format. My plan was to replace the word with a bold (or span) tag with the
    word within the tag. I've found the code below and it works fine as long
    as I'm not adding tags around the to parameter. Can anyone explain to me
    why it doesn't work with tags? And it needs to be XSLT 1.0.

    This works: X<xsl:value-of select="'little steak'"/>X
    This doesn't work: <b><xsl:value-of select="'little steak'"/></b>

    And the code:

    <?xml version="1.0"?>
    <xsl:styleshe et 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="substri ng-before($text, $from)"/>
    <xsl:variable name="after" select="substri ng-after($text, $from)"/>
    <xsl:variable name="prefix" select="concat( $before, $to)"/>

    <xsl:value-of select="$before "/>
    <xsl:value-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:otherwis e>
    <xsl:value-of select="$text"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    <!-- test the function -->
    <xsl:template match="/">
    <xsl:call-template name="replace-string">
    <xsl:with-param name="text"
    select="'Mary had a little lamb, little lamb, little lamb.'"/>
    <xsl:with-param name="from" select="'little lamb'"/>
    <xsl:with-param name="to">
    <!-- X<xsl:value-of select="'little steak'"/>X -->
    <b><xsl:value-of select="'little steak'"/></b>
    </xsl:with-param>
    </xsl:call-template>
    </xsl:template>
    </xsl:stylesheet>


  • Martin Honnen

    #2
    Re: Replace String

    Martin Honnen wrote:
    Hvid Hat wrote:
    >
    >I want to highlight (make it bold) a word in some text I'm getting in
    >XML format. My plan was to replace the word with a bold (or span) tag
    >with the word within the tag. I've found the code below and it works
    >fine as long as I'm not adding tags around the to parameter. Can
    >anyone explain to me why it doesn't work with tags? And it needs to be
    >XSLT 1.0.
    >
    You are using <xsl:value-of select="$to"/>, that outputs a text node
    with the string value, it does not create elements.
    If you use xsl:copy-of as in

    <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="substri ng-before($text, $from)"/>
    <xsl:variable name="after" select="substri ng-after($text, $from)"/>
    <xsl:variable name="prefix" select="concat( $before, $to)"/>

    <xsl:value-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:otherwis e>
    <xsl:value-of select="$text"/ </xsl:otherwise>
    </xsl:choose </xsl:template>

    then I think you get what you want.


    --

    Martin Honnen

    Comment

    • Hvid Hat

      #3
      Re: Replace String

      Thanks. Both your suggestions worked. Now I'm working on making the search
      case-insensitive. Is there an easy way? Or can you guide me in the right
      direction?

      Hello Martin,
      Martin Honnen wrote:
      >
      >Hvid Hat wrote:
      >>
      >>I want to highlight (make it bold) a word in some text I'm getting
      >>in XML format. My plan was to replace the word with a bold (or span)
      >>tag with the word within the tag. I've found the code below and it
      >>works fine as long as I'm not adding tags around the to parameter.
      >>Can anyone explain to me why it doesn't work with tags? And it needs
      >>to be XSLT 1.0.
      >>>
      >You are using <xsl:value-of select="$to"/>, that outputs a text node
      >with the string value, it does not create elements.
      >>
      If you use xsl:copy-of as in
      >
      <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="substri ng-before($text,
      $from)"/>
      <xsl:variable name="after" select="substri ng-after($text,
      $from)"/>
      <xsl:variable name="prefix" select="concat( $before, $to)"/>
      <xsl:value-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:otherwis e>
      <xsl:value-of select="$text"/ </xsl:otherwise>
      </xsl:choose </xsl:template>
      then I think you get what you want.
      >

      Comment

      • Hvid Hat

        #4
        Re: Replace String

        Hello Hvid,

        Ok. Now I can replace the search string no matter what case it's in. Unfortunately
        I haven't found a way to keep the original case of the search sting in the
        text. Anyone? Here's my code:

        <xsl:styleshe et xmlns:xsl="http ://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:variable name="lcletters ">abcdefghijklm nopqrstuvwxyz</xsl:variable>
        <xsl:variable name="ucletters ">ABCDEFGHIJKLM NOPQRSTUVWXYZ</xsl:variable>

        <xsl:template name="replace-string">
        <xsl:param name="text"/>
        <xsl:param name="from"/>
        <xsl:param name="to"/>
        <xsl:choose>
        <xsl:when test="contains( translate($text , $ucletters, $lcletters), translate($from ,
        $ucletters, $lcletters))">
        <xsl:variable name="before" select="substri ng-before(translat e($text,
        $ucletters, $lcletters), translate($from , $ucletters, $lcletters))"/>
        <xsl:variable name="after" select="substri ng-after(translate ($text, $ucletters,
        $lcletters), translate($from , $ucletters, $lcletters))"/>
        <xsl:variable name="prefix" select="concat( $before, $to)"/>
        <xsl:value-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:otherwis e>
        <xsl:value-of select="$text"/>
        </xsl:otherwise>
        </xsl:choose>
        </xsl:template>
        <xsl:template match="/">
        <xsl:call-template name="replace-string">
        <xsl:with-param name="text" select="'Mary had a little lamb, LITTLE LAMB,
        x little lamb.'"/>
        <xsl:with-param name="from" select="'little lamb'"/>
        <xsl:with-param name="to">
        <!-- X<xsl:value-of select="'little steak'"/>X -->
        <b>
        <xsl:value-of select="'little steak'"/>
        </b>
        </xsl:with-param>
        </xsl:call-template>
        </xsl:template>
        </xsl:stylesheet>

        Thanks. Both your suggestions worked. Now I'm working on making the
        search case-insensitive. Is there an easy way? Or can you guide me in
        the right direction?
        >
        Hello Martin,
        >
        >Martin Honnen wrote:
        >>
        >>Hvid Hat wrote:
        >>>
        >>>I want to highlight (make it bold) a word in some text I'm getting
        >>>in XML format. My plan was to replace the word with a bold (or
        >>>span) tag with the word within the tag. I've found the code below
        >>>and it works fine as long as I'm not adding tags around the to
        >>>parameter. Can anyone explain to me why it doesn't work with tags?
        >>>And it needs to be XSLT 1.0.
        >>>>
        >>You are using <xsl:value-of select="$to"/>, that outputs a text node
        >>with the string value, it does not create elements.
        >>>
        >If you use xsl:copy-of as in
        >>
        ><xsl:templat e name="replace-string">
        ><xsl:param name="text"/>
        ><xsl:param name="from"/>
        ><xsl:param name="to"/>
        ><xsl:choose>
        ><xsl:when test="contains( $text, $from)">
        ><xsl:variabl e name="before" select="substri ng-before($text,
        >$from)"/>
        ><xsl:variabl e name="after" select="substri ng-after($text,
        >$from)"/>
        ><xsl:variabl e name="prefix" select="concat( $before, $to)"/>
        ><xsl:value-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:otherwis e>
        ><xsl:value-of select="$text"/ </xsl:otherwise>
        ></xsl:choose </xsl:template>
        >then I think you get what you want.

        Comment

        Working...