Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何替换XSLT 1中的多个文本子字符串_Xml_Xslt - Fatal编程技术网

Xml 如何替换XSLT 1中的多个文本子字符串

Xml 如何替换XSLT 1中的多个文本子字符串,xml,xslt,Xml,Xslt,对于XSLT1.0,XSLT2.0的正则表达式方法通常不可用。是否有任何非正则表达式的方法来替换源xml文档中节点中的多个字段,例如转换: <?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 [[f

对于XSLT1.0,XSLT2.0的正则表达式方法通常不可用。是否有任何非正则表达式的方法来替换源xml文档中节点中的多个字段,例如转换:

<?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>

abc[[field1]]def[[field2]]ghi
致:


abc F def F ghi

EXSLT为您提供了一些好功能。如果需要替换简单字符串,请尝试。给出了XSLT1.0。

I.XSLT1.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>
<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>

应用于提供的XML文档时

<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>
<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>

abc[[field1]]def[[field2]]ghi
生成所需的正确结果

<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>
<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>

abc F def F ghi

II。XSLT 2.0解决方案(仅供比较):


编辑1

我刚刚意识到Dimitre的版本使用递归,并且非常相似;所以我的开场白现在看起来很傻

下面是一个使用递归的版本:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="fld-beg" select="'[['"/>
  <xsl:variable name="fld-end" select="']]'"/>
  <xsl:variable name="replacement" select="'F'"/>

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

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

  <xsl:template name="replace">
    <xsl:param name="str"/>
    <xsl:choose>
      <xsl:when test="contains($str, $fld-beg) and contains($str, $fld-end)">
        <xsl:call-template name="replace">
          <xsl:with-param name="str" select="concat(
            substring-before($str, $fld-beg),
            $replacement,
            substring-after($str, $fld-end))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$str"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

我希望这会有所帮助。

您可以在XSL中使用Java,例如replaceAll:

<xsl:template name="replace_all" xmlns:string="java.lang.String">
    <xsl:param name="text"/>
    <xsl:param name="pattern"/>
    <xsl:param name="replace"/>
    <xsl:variable name="text_string" select="string:new($text)"/>
    <xsl:value-of select="string:replaceAll($text_string, $pattern, $replace)"/>
</xsl:template>

模式是一个regexp。有关更多信息,请参阅:

您是否打算编写
version=“2.0”
?@lwburk:“XSLT 1”被明确地放在标题中——有人可以否决XSLT 2.0解决方案:)@lwburk:我添加了一个XSLT 2.0解决方案,包括短语:“仅供比较”:)我试图指出您的1.0解决方案说的是2.0,但比较也很有用。@lwburk:噢,我没注意到,谢谢。这显然是从我的XSelerator中早期未删除的代码中保留下来的,现在将更正版本。谢谢,我没有听说过EXSLT。很遗憾,我的
xsltproc
(在Debian上)版本中没有regex EXSLT函数-但结果是
replace
是:-)-很抱歉,我不能接受2个答案。