Замена строки XSLT
Я действительно не знаю 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>
может кто-нибудь сказать мне, что случилось с ним?
5 ответов:
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
как у вас было в оригинальном коде.
вот функция XSLT, которая будет работать аналогично строке.Заменить () функцию C#.
этот шаблон имеет 3 параметра, как показано ниже
текст :- ваша главная строку
заменить :- строку, которую вы хотите заменить
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>
ниже пример показывает, как назовите это
<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>
вы также можете обратиться к следующей ссылке за подробностями.
Примечание: в случае, если вы хотите использовать уже упомянутый algo для случаев, когда вам нужно заменить огромное количество экземпляров в исходной строке (например, новые строки в длинном тексте) есть высокий вероятность того, что вы закончите с
StackOverflowException
из-за рекурсивного вызова.Я решил эту проблему, спасибо отключено ' s (не смотрел, как это сделать в Саксон) встроенный тип встраивания 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>
вы можете использовать следующий код, когда ваш процессор работает на .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>
перед рекурсивным вызовом функции.
Я получил ответ от здесь: когда тест висит в бесконечном цикле
спасибо!