Функция translate()
может заменить только один символ другим одним символом (или пустым символом (удалить)).Таким образом, он не может решить проблему замены строки.
Вот полное решение XSLT 1.0 для задачи множественной замены :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<my:params xml:space="preserve">
<pattern>
<old>
</old>
<new><br/></new>
</pattern>
<pattern>
<old>quick</old>
<new>slow</new>
</pattern>
<pattern>
<old>fox</old>
<new>elephant</new>
</pattern>
<pattern>
<old>brown</old>
<new>white</new>
</pattern>
</my:params>
<xsl:variable name="vPats"
select="document('')/*/my:params/*"/>
<xsl:template match="text()" name="multiReplace">
<xsl:param name="pText" select="."/>
<xsl:param name="pPatterns" select="$vPats"/>
<xsl:if test="string-length($pText) >0">
<xsl:variable name="vPat" select=
"$vPats[starts-with($pText, old)][1]"/>
<xsl:choose>
<xsl:when test="not($vPat)">
<xsl:copy-of select="substring($pText,1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$vPat/new/node()"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="multiReplace">
<xsl:with-param name="pText" select=
"substring($pText, 1 + not($vPat) + string-length($vPat/old/node()))"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
, когда этопреобразование применяется к следующему XML-документу:
<t>The quick
brown fox</t>
желаемый, правильный результат получается :
The slow<br />white elephant
Объяснение :
Используется именованный шаблон, который вызывает себя рекурсивно.
Все пары множественных замен -> пары замены предоставляются в одномвнешний параметр, который для удобства здесь указывается inline как элемент глобального уровня <my:params>
.
Рекурсия принимает каждый отдельный символ в исходной строке (слева направо) и находитпервый шаблон, который начинается с этого символа в этой позиции в строке.
Замена может быть не только строкой, но и любым узлом.В этом конкретном случае мы заменяем каждый символ NL элементом <br/>
.