XSLT 1.0 не имеет надежного текстового поиска и замены. Вы можете создать что-то, что использует contains
, substring-before
и substring-after
, но вы должны использовать рекурсивный шаблон для обработки случая, когда строка, которую вы пытаетесь исправить, имеет несколько вхождений подстроки. *
Это работает при условии, что ваше преобразование, которое перемещает и переименовывает элементы, является вариантом преобразования идентичности:
<xsl:template match="text()">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, 'bar')">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="concat(
substring-before($text, 'bar'),
'myBar',
substring-after($text, 'bar'))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Обратите внимание, что где бы вы ни копировали значение элемента, используя value-of
, вам нужно использовать apply-templates
; изменить это:
<xsl:template match="someElement">
<renamedElement>
<xsl:value-of select="."/>
<renamedElement>
</xsl:template>
в это:
<xsl:template match="someElement">
<renamedElement>
<xsl:apply-templates select="text()"/>
<renamedElement>
</xsl:template>
Делать несколько замен немного сложнее. Вы должны расширить шаблон replace
, чтобы получить аргументы searchFor
и replaceWith
, что достаточно просто, а затем сделать это в шаблоне text()
:
<xsl:variable name="pass1">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="searchFor">bar</xsl:with-param>
<xsl:with-param name="replaceWith">myBar</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="pass2">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="searchFor">bar</xsl:with-param>
<xsl:with-param name="replaceWith">myBar</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$pass2"/>
В XSLT 2.0, который поддерживает использование регулярных выражений на текстовых узлах, это намного проще. Вы по-прежнему создаете шаблон, который соответствует text()
, но он просто вызывает replace
. См. эту статью для получения дополнительной информации, если вам посчастливилось использовать XSLT 2.0.