Регулярные выражения в xsl:template соответствуют атрибуту

Я просто хочу знать, возможно ли использовать регулярные выражения в 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 атрибут?

Большое спасибо

7
задан bluish 4 October 2011 в 14:44
поделиться

2 ответа

Вот правильный способ сопоставления в 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>
15
ответ дан 6 December 2019 в 09:18
поделиться

В XSLT 1.0 (и 2.0 тоже), для вашего примера (хотя это не регулярное выражение):

<xsl:template match="*[contains(name(), 'line')]">
  <xsl:value-of select="."/>
</xsl:template>

и для достижения соответствия конца строки:

<xsl:template match="*[contains(concat(name(), '&#xA;'), 'line&#xA;')]">
  <xsl:value-of select="."/>
</xsl:template>

В XSLT 2.0 вы, конечно, можете использовать функция match () вместо содержит () .

5
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: