XSLT字符串替换

Axi*_*ili 82 xslt xpath replace xpath-1.0 xslt-1.0

我真的不知道XSL但是我需要修复这个代码,我已经减少了它以使它更简单.
我收到了这个错误

无效的XSLT/XPath函数

在这条线上

<xsl:variable name="text" select="replace($text,'a','b')"/>
Run Code Online (Sandbox Code Playgroud)

这是XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:inm="http://www.inmagic.com/webpublisher/query" version="1.0">
    <xsl:output method="text" encoding="UTF-8" />

    <xsl:preserve-space elements="*" />
    <xsl:template match="text()" />

    <xsl:template match="mos">
        <xsl:apply-templates />

        <xsl:for-each select="mosObj">
          'Notes or subject' 
           <xsl:call-template
                name="rem-html">
                <xsl:with-param name="text" select="SBS_ABSTRACT" />
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="rem-html">
        <xsl:param name="text" />
        <xsl:variable name="text" select="replace($text, 'a', 'b')" />
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

谁能告诉我它有什么问题?

Mar*_*iot 135

replace 不适用于XSLT 1.0.

编码有一个字符串替换模板,您可以用它作为函数的替代:

<xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
        <xsl:when test="$text = '' or $replace = ''or not($replace)" >
            <!-- Prevent this routine from hanging -->
            <xsl:value-of select="$text" />
        </xsl:when>
        <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>
Run Code Online (Sandbox Code Playgroud)

调用为:

<xsl:variable name="newtext">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="$text" />
        <xsl:with-param name="replace" select="a" />
        <xsl:with-param name="by" select="b" />
    </xsl:call-template>
</xsl:variable>
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您只需要将一个字符替换为另一个字符,则可以调用translate具有相似签名的字符.像这样的东西应该工作正常:

<xsl:variable name="newtext" select="translate($text,'a','b')"/>
Run Code Online (Sandbox Code Playgroud)

Also, note, in this example, I changed the variable name to "newtext", in XSLT variables are immutable, so you can't do the equivalent of $foo = $foo like you had in your original code.

  • 这个答案错了​​!XSLT中的replace函数替换相应的SINGLE CHARACTERS,而不是整个字符串!例如,请参见:http://www.w3schools.com/xpath/xpath_functions.asp (18认同)
  • @Jakub你想的是'translate`,而不是`replace`.XPath 2.0中的`replace`函数将其第二个参数视为_regular expression_,并将该表达式的所有匹配替换为指定的替换字符串(可能包括对正则表达式中捕获组的`$ n`引用).`translate`函数(在1.0和2.0中)是单个字符替换单个字符的函数. (12认同)
  • 不应该在示例用法中的第4行是`<xsl:with-param name ="replace"select ="'a'"/>`在a附近引用? (6认同)

小智 36

这是XSLT函数,它的工作方式类似于C#的String.Replace()函数.

此模板具有3个参数,如下所示

text: - 你的主要字符串

replace: - 要替换​​的字符串

by: - 将用新字符串回复的字符串

以下是模板

<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>
Run Code Online (Sandbox Code Playgroud)

下面的示例显示了如何调用它

<xsl:variable name="myVariable ">
  <xsl:call-template name="string-replace-all">
    <xsl:with-param name="text" select="'This is a {old} text'" />
    <xsl:with-param name="replace" select="'{old}'" />
    <xsl:with-param name="by" select="'New'" />
  </xsl:call-template>
</xsl:variable>
Run Code Online (Sandbox Code Playgroud)

您还可以参考以下URL以获取详细信息.

  • 使用 xslt 1.0 这篇文章/模板对我有用,而 Mark Elliot 的则不然。 (2认同)

Mil*_*sić 12

注意:如果你想使用算法中已经提到的,你需要替换源字符串中的情况下(在长文本如新行),有数量巨大的情况下较高的概率你会结束了StackOverflowException,因为递归呼叫.

我解决了这个问题,感谢Xalan(看起来不怎么在Saxon中做)内置的Java类型嵌入:

<xsl:stylesheet version="1.0" exclude-result-prefixes="xalan str"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xalan="http://xml.apache.org/xalan"
                xmlns:str="xalan://java.lang.String"
        >
...
<xsl:value-of select="str:replaceAll(
    str:new(text()),
    $search_string,
    $replace_string)"/>
...
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

  • 我的评论是针对最流行的Java XSLT 1.0引擎Xalan(https://xml.apache.org/xalan-j/),它支持直接映射到可用Java类路径中的可用类型; 你无法为.Net堆栈应用我的解决方案 (3认同)

小智 7

当处理器在.NET上运行或使用MSXML(而不是基于Java或其他本机处理器)时,可以使用以下代码.它使用msxsl:script.

确保将命名空间添加xmlns:msxsl="urn:schemas-microsoft-com:xslt"到根xsl:stylesheetxsl:transform元素.

另外,例如,绑定outlet到您喜欢的任何命名空间xmlns:outlet = "http://my.functions".

<msxsl:script implements-prefix="outlet" language="javascript">
function replace_str(str_text,str_replace,str_by)
{
     return str_text.replace(str_replace,str_by);
}
</msxsl:script>


<xsl:variable name="newtext" select="outlet:replace_str(string(@oldstring),'me','you')" />
Run Code Online (Sandbox Code Playgroud)


Ber*_*oer 6

我一直在打这个答案。但是它们都没有列出 xsltproc 的最简单解决方案(可能还有大多数 XSLT 1.0 处理器):

  1. 将 exslt 字符串名称添加到样式表中,即:
<xsl:stylesheet
  version="1.0"
  xmlns:str="http://exslt.org/strings"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Run Code Online (Sandbox Code Playgroud)
  1. 然后像这样使用它:
<xsl:value-of select="str:replace(., ' ', '')"/>
Run Code Online (Sandbox Code Playgroud)

  • 我的计算机(macOS 10.13)上的 xsltproc 不支持 `str:replace()` 函数。其他主要 XSLT 1.0 处理器 - Xalan、Saxon 6.5 和 Microsoft 也没有。 (3认同)