Я действительно не знаю 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>
Кто-нибудь может сказать мне, что с этим не так?
replace()
функция доступна начиная с XPath 2.0 (и, следовательно, XSLT 2.0) и далее и поддерживает замену регулярных выражений.Ответы:
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
что и в исходном коде.источник
translate
, не такreplace
.replace
Функция в XPath 2.0 обрабатывает ее второй аргумент как регулярное выражение и заменяет все матчи этого выражения с указанной строкой замены (которая может включать в себя$n
ссылку на группы захвата в регулярном выражении). Этаtranslate
функция (в версиях 1.0 и 2.0) выполняет замену одного символа на один.<xsl:with-param name="replace" select="'a'" />
кавычки a?Вот функция XSLT, которая будет работать аналогично функции String.Replace () в C #.
Этот шаблон имеет 3 параметра, как показано ниже.
text : - ваша основная строка
replace : - строка, которую вы хотите заменить
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>
Вы также можете обратиться к указанному ниже URL-адресу для получения подробной информации.
источник
Примечание: если вы хотите использовать уже упомянутый алгоритм для случаев, когда вам нужно заменить огромное количество экземпляров в исходной строке (например, новые строки в длинном тексте), высока вероятность того, что вы столкнетесь с
StackOverflowException
рекурсивным вызов.Я решил эту проблему благодаря встроенному в Xalan (не смотрел, как это сделать в Saxon ) 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>
источник
Cannot find a script or an extension object associated with namespace 'xalan://java.lang.String'.
<msxsl:script>
блок, который может вызывать любой метод .NET, библиотеку и т.д. Хотя .NET также поддерживает функции расширения EXSLT, поэтому вам не нужно.Вы можете использовать следующий код, когда ваш процессор работает на .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')" />
источник
prefix outlet is not defined
или'xsl:script' cannot be a child of the 'xsl:stylesheet' element.
меняю msxsl на свой префикс. Я предполагаю, что это какая-то магия XSLT от Microsoft?xsl:script
, но уmsxsl:script
него другое пространство имен (я обновил ответ Джона).Я продолжаю набирать этот ответ. Но ни один из них не перечисляет самое простое решение для xsltproc (и, вероятно, для большинства процессоров XSLT 1.0):
<xsl:stylesheet version="1.0" xmlns:str="http://exslt.org/strings" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:value-of select="str:replace(., ' ', '')"/>
источник
str:replace()
функцию. Как и ни один из других основных процессоров XSLT 1.0 - Xalan, Saxon 6.5 и Microsoft.Руина довольно хороша, однако из-за нее мое приложение зависает, поэтому мне нужно было добавить случай:
<xsl:when test="$text = '' or $replace = ''or not($replace)" > <xsl:value-of select="$text" /> <!-- Prevent thsi routine from hanging --> </xsl:when>
до того, как функция будет вызвана рекурсивно.
Я получил ответ отсюда: При тестировании зависает в бесконечном цикле
Спасибо!
источник