问题
I have an XML document that I'm trying to transform and do a string replace of certain values when that value occurs in either a text node or an attribute named message. My xsl file is below, but the main issue is that when the replace occurs in the message attribute, it actually replaces the whole attribute and not just the value of that attribute, so
<mynode message="hello, replaceThisText"></mynode>
becomes
<mynode>hello, withThisValue</mynode>
Instead of
<mynode message="hello, withThisValue"></mynode>
When the text occurs in a text node like
<mynode>hello, replaceThisText</mynode>
Then it works as expected.
I haven't done a ton of XSLT work, so I'm a bit stuck here. Any help would be appreciated. Thanks.
<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>
回答1:
Your template matches an attribute, but it doesn't output one.
Note that the value of an attribute is not a node. Therefore, you must use separate templates for text nodes and for the 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>
来源:https://stackoverflow.com/questions/27805510/xslt-replacing-text-in-attribute-value-and-text-nodes