XSLT字符串替换XSLT字符串替换(XSLT string replace)

2019-05-10 13:00发布

我真的不知道XSL,但我需要解决这个问题的代码,我已经减少了它,使其更简单。
我得到这个错误

无效的XSLT / XPath函数

在这条线

<xsl:variable name="text" select="replace($text,'a','b')"/>

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

谁能告诉我有什么错呢?

Answer 1:

replace不适用于XSLT 1.0。

Codesling有一个模板字符串替换就可以作为函数的替代品使用:

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

援引为:

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

在另一方面,如果你从字面上只需要与另一个替换一个字符,你可以调用translate具有类似的签名。 这样的事情应该很好地工作:

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

此外,请注意,在这个例子中,我改变了变量名“newtext”,在XSLT变量是不变的,所以你不能这样做相当于$foo = $foo喜欢你在原来的代码了。



Answer 2:

这里是XSLT的功能,这将工作类似的与string.replace C#()函数。

这个模板有如下3个参数

文本 : -你的主串

替换 : -要替换的字符串

通过 : -字符串将由新的字符串回复

下面是模板

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

下面的示例演示如何调用它

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

您也可以参考以下网址了解详细情况。



Answer 3:

注意:如果你想使用算法中已经提到的,你需要替换源字符串中的情况下(在长文本如新线)的数量庞大的情况下,有很高的概率你会最终StackOverflowException因递归调用。

我解决了这个问题,感谢的Xalan的(不看怎么做,在撒克逊 )内置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>


Answer 4:

当你的处理器上运行的.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')" />


Answer 5:

该rouine是相当不错的,但是它会导致我的应用程序挂起,所以我需要补充的情况下:

  <xsl:when test="$text = '' or $replace = ''or not($replace)" >
    <xsl:value-of select="$text" />
    <!-- Prevent thsi routine from hanging -->
  </xsl:when>

之前的函数被递归调用。

我得到的答案从这里: 当测试挂在一个无限循环

谢谢!



文章来源: XSLT string replace