Строка 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>
Может ли кто-нибудь сказать мне, что с ним не так?
Ответы
Ответ 1
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
, как в исходном коде.
Ответ 2
Вот функция XSLT, которая будет работать аналогично функции 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>
Вы также можете обратиться к ниже URL.
Ответ 3
Примечание.. Если вы хотите использовать уже упомянутый алгоритм для случаев, когда вам нужно заменить огромное количество экземпляров в исходной строке (например, новые строки в длинном тексте), существует высокая вероятность вы получите StackOverflowException
из-за рекурсивного вызова.
Я решил эту проблему благодаря Xalan (не смотрел, как это сделать в встроенном встроенном встроенном Java-стиле Saxon):
<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>
Ответ 4
Вы можете использовать следующий код, когда ваш процессор работает на .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')" />
Ответ 5
Подлинная очень хороша, но это приводит к зависанию моего приложения, поэтому мне нужно добавить случай:
<xsl:when test="$text = '' or $replace = ''or not($replace)" >
<xsl:value-of select="$text" />
<!-- Prevent thsi routine from hanging -->
</xsl:when>
прежде чем функция будет вызвана рекурсивно.
Я получил ответ отсюда:
Когда тест висит в бесконечном цикле
Спасибо!