XSLT replaces text in attribute value and text nodes

I have an XML document that I am trying to transform and am replacing the string with some values ​​when that value occurs either in the text of a node or an attribute with a name. My xsl file is below, but the main problem is that when a replacement happens on a post attribute, it actually replaces the entire attribute, not just the value of that attribute, so

<mynode message="hello, replaceThisText"></mynode>

      

becomes

<mynode>hello, withThisValue</mynode>

      

Instead

<mynode message="hello, withThisValue"></mynode>

      

When text appears in a text node like

<mynode>hello, replaceThisText</mynode>

      

Then it works as expected.

I haven't done the fine work of XSLT, so I'm a bit stuck here. Any help would be greatly appreciated. Thank.

<xsl:template match="text()|@message">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text"><xsl:value-of select="."/></xsl:with-param>
        <xsl:with-param name="replace" select="'replaceThisText'"/>             
        <xsl:with-param name="by" select="'withThisValue'"/>
    </xsl:call-template>
</xsl:template>

<!-- string-replace-all from http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx -->
<xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)" />
        <xsl:value-of select="$by" />
        <xsl:call-template name="string-replace-all">
          <xsl:with-param name="text"
          select="substring-after($text,$replace)" />
          <xsl:with-param name="replace" select="$replace" />
          <xsl:with-param name="by" select="$by" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text" />
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>

      

0


source to share


1 answer


Your template matches the attribute, but it doesn't output it.

Note that the attribute value is not node. Therefore, you must use separate templates for text nodes and for an attribute:



<xsl:template match="text()">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="."/>
        <xsl:with-param name="replace" select="'replaceThisText'"/>             
        <xsl:with-param name="by" select="'withThisValue'"/>
    </xsl:call-template>
</xsl:template>

<xsl:template match="@message">
    <xsl:attribute name="message">
        <xsl:call-template name="string-replace-all">
            <xsl:with-param name="text" select="."/>
            <xsl:with-param name="replace" select="'replaceThisText'"/>             
            <xsl:with-param name="by" select="'withThisValue'"/>
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

      

+2


source







All Articles