如何替换 XSLT 1 中的多个文本子字符串 [英] How to replace multiple text substrings in XSLT 1

查看:26
本文介绍了如何替换 XSLT 1 中的多个文本子字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 XSLT 1.0 中,XSLT 2.0 的正则表达式方法通常不可用.是否有任何非正则表达式替换源 xml 文档中节点中的多个字段的方法,例如转换:

With XSLT 1.0, the regex methods of XSLT 2.0 are generally unavailable. Is there any non-regex way of replacing multiple fields in a node in a source xml document, for example to convert:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
  <file>
    <source>abc [[field1]] def [[field2]] ghi</source>
  </file>
</xliff>

到:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
  <file>
    <source>abc F def F ghi</source>
  </file>
</xliff>

推荐答案

I.XSLT 1.0 解决方案:

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTargetStart" select="'[['"/>
 <xsl:param name="pTargetEnd" select="']]'"/>
 <xsl:param name="pReplacement" select="'F'"/>

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

 <xsl:template match="source/text()" name="replace">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pTargetStart" select="$pTargetStart"/>
  <xsl:param name="pTargetEnd" select="$pTargetEnd"/>
  <xsl:param name="pRep" select="$pReplacement"/>

  <xsl:choose>
   <xsl:when test=
    "not(contains($pText, $pTargetStart)
       and
        contains($pText, $pTargetEnd)
        )
     or
      not(contains(substring-after($pText, $pTargetStart),
                   $pTargetEnd
                   )
         )
    ">
     <xsl:value-of select="$pText"/>
    </xsl:when>

    <xsl:otherwise>
     <xsl:value-of select="substring-before($pText, $pTargetStart)"/>
     <xsl:value-of select="$pRep"/>

     <xsl:variable name="vremText" select=
     "substring-after(substring-after($pText, $pTargetStart),
                      $pTargetEnd
                      )"/>
     <xsl:call-template name="replace">
      <xsl:with-param name="pText" select="$vremText"/>
      <xsl:with-param name="pTargetStart" select="$pTargetStart"/>
      <xsl:with-param name="pTargetEnd" select="$pTargetEnd"/>
      <xsl:with-param name="pRep" select="$pRep"/>
     </xsl:call-template>
    </xsl:otherwise>

  </xsl:choose>

 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
    <file>
        <source>abc [[field1]] def [[field2]] ghi</source>
    </file>
</xliff>

产生想要的、正确的结果:

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
   <file>
      <source>abc F def F ghi</source>
   </file>
</xliff>

<小时>

二.XSLT 2.0 解决方案(仅供对比):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="source/text()">
  <xsl:sequence select="replace(., '\[\[(.*?)\]\]', 'F')"/>
 </xsl:template>
</xsl:stylesheet>

这篇关于如何替换 XSLT 1 中的多个文本子字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆