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:stylesheet
或xsl: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挂在一个无限循环
谢谢!