XSLTstringreplace

我真的不知道XSL,但我需要修复这个代码,我已经减less了它,使其更简单。
我得到这个错误

无效的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> 

谁能告诉我这有什么问题吗?

replace不适用于XSLT 1.0。

Codesling有一个stringreplace的模板,你可以用它来代替函数:

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

另一方面,如果你真的只需要用另一个字符replace一个字符,就可以调用具有相似签名的translate 。 像这样的东西应该可以正常工作:

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

另外,请注意,在本例中,我将variables名称更改为“newtext”,在XSLTvariables中是不可变的,因此您不能像原始代码那样执行相同的$foo = $foo

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

这个模板有3个参数如下

文本 : – 你的主要string

replace : – 你想要replace的string

通过 : – 将通过新string回复的string

以下是模板

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

您也可以参考下面的url获取详细信息。

注意:如果你希望使用已经提到的algorithm,你需要replace源string中的大量实例(例如长文本中的新行),那么很有可能最终会出现StackOverflowException因为recursion调用。

我解决了这个问题,这要归功于Xalan (在Saxon没有看到如何做)内置的Javatypesembedded:

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

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

理由是相当不错,但它会导致我的应用程序挂起,所以我需要添加案件:

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

在函数被recursion调用之前。

我从这里得到了答案: 当testing挂在一个无限循环

谢谢!