Я просто хочу знать, возможно ли использовать регулярные выражения в match
атрибут xsl:template
элемент. Например, предположите, что у меня есть следовать XML-документ:
<greeting>
<aaa>Hello</aaa>
<bbb>Good</bbb>
<ccc>Excellent</ccc>
<dddline>Line</dddline>
</greeting>
Теперь XSLT для преобразования вышеупомянутого документа:
<xsl:stylesheet>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="matches(node-name(*),'line')">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Когда я пытаюсь использовать синтаксис matches(node-name(*),'line$')
в match
атрибут xsl:template
элемент, это получает сообщение об ошибке. Я могу использовать регулярные выражения в match
атрибут?
Большое спасибо
Вот правильный способ сопоставления в XSLT 1.0 (в XSLT 2. 0 используйте функцию matches() с реальным RegEx в качестве аргумента pattern
):
Поиск элемента, имя которого содержит 'line'
:
<xsl:template match="*[contains(name(), 'line')]">
<!-- Whatever processing is necessary -->
</xsl:template>
Поиск элемента, имя которого заканчивается на 'line'
:
<xsl:template match="*[substring(name(), string-length() -3) = 'line']">
<!-- Whatever processing is necessary -->
</xsl:template>
@Tomalak предоставил другой способ XSLT 1.0 для поиска имен, которые заканчиваются заданной строкой. Его решение использует специальный символ, который гарантированно не будет присутствовать ни в одном имени. Мое решение может быть применено для поиска того, заканчивается ли любая строка (не только имя элемента) другой заданной строкой.
В XSLT 2.x :
Use: matches(name(), '.*line$')
для поиска имен, которые заканчиваются строкой "line"
Это преобразование:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*[matches(name(), '.*line$')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*[not(matches(name(), '.*line$'))]">
<xsl:apply-templates select="node()[not(self::text())]"/>
</xsl:template>
</xsl:stylesheet>
при применении к XML документу:
<greeting>
<aaa>Hello</aaa>
<bblineb>Good</bblineb>
<ccc>Excellent</ccc>
<dddline>Line</dddline>
</greeting>
Копирует на вывод только элемент, имя которого заканчивается строкой "line"
:
<dddline>Line</dddline>
Пока это преобразование (использует matches(name(), '. *line')
):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="*[matches(name(), '.*line')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*[not(matches(name(), '.*line'))]">
<xsl:apply-templates select="node()[not(self::text())]"/>
</xsl:template>
</xsl:stylesheet>
копирует в вывод все элементы, имена которых содержат строку "line"
:
<bblineb>Good</bblineb>
<dddline>Line</dddline>
В XSLT 1.0 (и 2.0 тоже), для вашего примера (хотя это не регулярное выражение):
<xsl:template match="*[contains(name(), 'line')]">
<xsl:value-of select="."/>
</xsl:template>
и для достижения соответствия конца строки:
<xsl:template match="*[contains(concat(name(), '
'), 'line
')]">
<xsl:value-of select="."/>
</xsl:template>
В XSLT 2.0 вы, конечно, можете использовать функция match ()
вместо содержит ()
.