对所有XML(XSLT)的一般替换

ada*_*m_0 0 xml xslt replace xslt-2.0

基本上,我现在正在做的是运行XSLT,然后在Visual Studio中打开结果并执行查找和替换一个单词 - 对于此示例,我想将"bar"的所有实例更改为"myBar".可以假设"bar"的所有实例都在文本元素中,如下所示:

<someElement>bar.whatever</someElement>
Run Code Online (Sandbox Code Playgroud)

这将转变为:

<someElement>myBar.whatever</someElement>
Run Code Online (Sandbox Code Playgroud)

但需要注意的是,我还在运行其他转换,例如重命名或移动元素.有没有什么方法可以将这两个操作(转换和查找和替换)组合成一个XSLT?这可能是多次查找和替换吗?

所有帮助表示赞赏,并提前致谢!

编辑:来自评论

我应该指出我确实使用XSLT 2.0.我正在阅读那篇文章并试图找出如何使用replace()

Rob*_*ney 5

XSLT 1.0没有强大的文本搜索和替换功能.您可以使用杜松子酒的东西了contains,substring-beforesubstring-after,但你必须使用递归模板来处理,你正在试图修复该字符串有子多次出现的情况.

这是有效的,假设您移动和重命名元素的变换是身份变换的变体:

<xsl:template match="text()">
  <xsl:call-template name="replace">
    <xsl:with-param name="text" select="."/>
  </xsl:call-template>
</xsl:template>

<xsl:template name="replace">
  <xsl:param name="text"/>
  <xsl:choose>
    <xsl:when test="contains($text, 'bar')">
      <xsl:call-template name="replace">
        <xsl:with-param name="text" select="concat(
                        substring-before($text, 'bar'), 
                        'myBar',
                        substring-after($text, 'bar'))"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

请注意,无论您在何处复制元素的值value-of,都需要使用apply-templates; 改变这个:

<xsl:template match="someElement">
   <renamedElement>
      <xsl:value-of select="."/>
   <renamedElement>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

进入这个:

<xsl:template match="someElement">
   <renamedElement>
      <xsl:apply-templates select="text()"/>
   <renamedElement>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

做多次替换有点棘手.您必须扩展replace模板以获取searchForreplaceWith参数,这很容易,然后在text()模板中执行此操作:

<xsl:variable name="pass1">
   <xsl:call-template name="replace">
      <xsl:with-param name="text" select="."/>
      <xsl:with-param name="searchFor">bar</xsl:with-param>
      <xsl:with-param name="replaceWith">myBar</xsl:with-param>
   </xsl:call-template>
</xsl:variable>

<xsl:variable name="pass2">
   <xsl:call-template name="replace">
      <xsl:with-param name="text" select="."/>
      <xsl:with-param name="searchFor">bar</xsl:with-param>
      <xsl:with-param name="replaceWith">myBar</xsl:with-param>
   </xsl:call-template>
</xsl:variable>

<xsl:value-of select="$pass2"/>
Run Code Online (Sandbox Code Playgroud)

在XSLT 2.0中,它支持在文本节点上使用正则表达式,这更容易.您仍然可以创建匹配的模板text(),但它只是有一个调用replace.如果您有幸能够使用XSLT 2.0,请参阅此文章以获取大量信息.