XSLT replacing text in attribute value and text nodes

时间秒杀一切 提交于 2020-01-25 04:26:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!