XSL 替换富文本中的属性

XSL replace attribute inside richtext

我想更改 xml 节点的内容。 这是我的来源:

<content>
    <p>
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. 
        <a href="http://www.example.com">
            <strong>http://www.example.com</strong>
        </a>
    At vero eos et accusam et justo duo dolores et ea rebum. 
   </p>
</content>

我想将 -Tag 中的部分更改为以下结果:

<content>
                    <p>
                        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. 
                        <a xlink:show="new" xlink:href="http://www.example.com" xlink:type="simple">
                            <strong>http://www.example.com</strong>
                        </a>
                        At vero eos et accusam et justo duo dolores et ea rebum. 
                    </p>
            </content>

所以,基本上我想将 "href" 更改为 xlik:href。其他一切都应该保持不变,比如

-tag 或 -Tag.

我希望我能做这样的事情:

    <xsl:for-each select=".../content">    

....
....

    <xsl:variable name="content">
            <xsl:copy-of select="content/node()" />
        </xsl:variable>

    <xsl:value-of select="replace($content, 'href', 'xlink:href')" />

....
....

    <xsl:for-each/>

但结果是,所有标签和属性都消失了:

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.

                      http://www.example.com

                  At vero eos et accusam et justo duo dolores et ea >rebum.

如何才能仅更改 href-Attribute?

首先从身份模板开始

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

然后有一个与 a 元素相匹配的模板,它会创建一个具有您需要的属性的新 a 元素。

<xsl:template match="a">
  <a xlink:show="new" xlink:href="{@href}" xlink:type="simple">
    <xsl:apply-templates select="@*[name()!='href']|node()"/>
  </a>
</xsl:template>

这假设您在 XSLT 中定义了 xlink 命名空间前缀。

试试这个 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="a">
    <a xlink:show="new" xlink:href="{@href}" xlink:type="simple">
      <xsl:apply-templates select="@*[name()!='href']|node()"/>
    </a>
  </xsl:template>
</xsl:stylesheet>

编辑:在回答您的评论时,您实际上并不需要 xsl:for-each ,除非您实际上正在进行其他转换,而不仅仅是更改 href 属性。模板方法通常是可行的方法,绝对值得学习。但如果有帮助,这里有一个使用 xsl:for-each 的样式表,您可以根据自己的需要进行调整:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:for-each select="content">
    ...
    <content>
      <xsl:apply-templates select="@*|node()"/>
    </content>
    ...
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="a">
    <a xlink:show="new" xlink:href="{@href}" xlink:type="simple">
      <xsl:apply-templates select="@*[name()!='href']|node()"/>
    </a>
  </xsl:template>
</xsl:stylesheet>