XSLT - как XSLT-процессор соответствует шаблонам

Я пытаюсь понять основную идею работы XSLT 1.0. Я использую браузер Firefox для обучения. Следующий пример практически не практичен, а скорее иллюстрирует базу для моего вопроса.

Для исходного XML-документа:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="helloworld.xsl"?>

<messages>
    <greeting>Hello World!</greeting>
    <farewell>Bye World!</farewell>
</messages>

И таблица стилей:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="4.0" encoding="UTF-8" />

        <xsl:template match="greeting">
            <b><xsl:value-of select="." /></b>
        </xsl:template>

        <xsl:template match="farewell">
            <b><xsl:value-of select="." /></b>
        </xsl:template>

</xsl:stylesheet>

Я получаю «Привет, Word!» и «Bye World!» выделено жирным шрифтом. Если я использую следующую таблицу стилей:

   <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="html" version="4.0" encoding="UTF-8" />

            <xsl:template match="greeting">
                <b><xsl:value-of select="." /></b>
            </xsl:template>

            <xsl:template match="greeting">
                <i><xsl:value-of select="." /></i>
            </xsl:template>

    </xsl:stylesheet>

Затем «Bye World!» как и ожидалось, не смел, но «Hello World» тоже не смел, только курсивом. Что случилось? В первой версии таблицы стилей кажется, что оба шаблона, где выполняется - оба совпадают с узлом документа. Во второй версии кажется, что только вторая была выполнена или ее вывод был перезаписан первым. Я был бы очень благодарен за объяснение, на каком основании XSLT-процессор сопоставляет узлы с шаблонами в обеих таблицах стилей.

Из того, что я понимаю: в начале узла документа преобразования выбран как контекст. Процессор XSLT выполняет итерацию по узлам в контексте и пытается найти шаблон для каждого узла, который будет соответствовать и исполнять. Контекст - синоним «текущего узла». Я не понимаю: обрабатывает ли процессор через узлы, являющиеся дочерними узлами текущего узла (поэтому в моем примере только узел сообщения, поскольку он является единственным дочерним узлом узла документа) или через все узлы, являющиеся потомком текущего узла?

Всего 1 ответ


Чтобы понять, что произошло, вы должны посмотреть на код HTML, созданный в результате преобразования XSL, а не на то, как этот код отображается на экране. Ты получаешь:

<i>Hello World!</i>
Bye World!

Первая строка создается с помощью (последнего) шаблона, соответствующего greeting *. Вторая строка создается встроенными правилами шаблонов, которые обрабатывают farewell элемент в отсутствие соответствующего шаблона. Эти шаблоны копируют любые текстовые узлы на выходе.


(*) Ошибка состоит из двух конфликтующих шаблонов. Однако спецификация позволяет процессору игнорировать ошибку и применять последний шаблон соответствия в документе XSLT.


Есть идеи?

10000