XSLT字符串替换

问题描述:

我并不十分了解XSL,但我需要修复此代码,我已经减少了它以使其更简单。
我收到此错误XSLT字符串替换

Invalid XSLT/XPath function

在这条线

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

谁能告诉我有什么错呢?

+0

请注意''replace()'函数可从XPath 2.0(因此XSLT 2.0)开始使用,并支持正则表达式替换。 – Abel 2015-09-24 23:55:03

replace不适用于XSLT 1.0。

Codesling有template for string-replace可以作为功能的替代品使用:援引为

<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相当于喜欢你在您的原始代码。

+0

感谢马克,但现在我得到这个错误: 一个未知的XPath扩展函数被调用 – Aximili 2010-06-18 04:23:59

+0

@aximili,对不起,得到XSLT 1.0和2.0困惑,编辑...应该是现在就去吧。 – 2010-06-18 04:37:54

+0

我看到谢谢马克! – Aximili 2010-06-18 05:09:37

这里是XSLT函数,其功能类似于C#的String.Replace()函数。

这个模板有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> 

您也可以参考below URL的细节。

+0

使用xslt 1.0这篇文章/模板适用于我,而Mark Elliot没有。 – HostMyBus 2016-09-07 09:05:22

注:如果你想使用在您需要替换源字符串中的情况下,数量巨大的情况下(在长文本如新线)有概率已经提到的算法中你”由于递归调用,最终会得到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> 
+0

对不起,如果我是哑巴,但我得到:'找不到与命名空间'xalan:// java.lang.String'关联的脚本或扩展对象。' – 2014-08-13 09:08:15

+0

什么是您的XSLT引擎? – 2014-08-13 18:40:19

+0

微软.NET恐怕... – 2014-08-14 08:42:53

您可以使用下面的代码时您的处理器在.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')" /> 
+0

对不起,如果我愚蠢,但我得到'前缀outlet没有定义'或''xsl:script'不能是'xsl:stylesheet'元素的子元素.'如果我更改我的前缀msxsl。我猜这是一些微软特定的XSLT魔术? – 2014-08-13 09:02:39

+1

@IngGrainger,它不是'xsl:script',而是'msxsl:script',它有一个不同的命名空间(我已经更新了John的答案)。 – Abel 2015-09-24 23:48:36

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

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

之前的函数被递归调用。

我得到的答案从这里: When test hanging in an infinite loop

谢谢!