Я смущен оператором применять-шаблона XSLT. Например, здесь в w3school.
http://www.w3schools.com/xsl/xsl_apply_templates.asp
Для операторов,
My CD Collection
мои беспорядки,
(1) из чего функция
? Это не содержит определенного шаблона для вызова. Я думаю, что это соответствует, (возвратит) все непосредственно ребенок элемента тока (непрямой ребенок текущего узла не будет возвращен, текущий узел является корневым узлом), не уверенный, корректен ли я?
(2) после того, как все подобранные узлы возвращаются в (1), каков следующий процессор XSLT шага, сделает?
(3) в этом specifc образце корневой узел является каталогом или другим более высоким уровнем корня? и почему?
заранее спасибо, George
Некоторые вещи, которые облегчат понимание ответов:
В первую очередь, узлы и элементы не одно и то же . Элементы - это узлы, но узлы не обязательно являются элементами. Вы часто находите людей, использующих термины взаимозаменяемыми. На самом деле в XML существует четыре вида узлов: элементы, текстовые узлы, инструкции по обработке и комментарии. (Атрибуты на самом деле не являются узлами, к которым я приду через секунду)
В XSLT корень XML-документа не является его верхним элементом; корень - это абстракция, которая на самом деле не существует. Элемент верхнего уровня является дочерним по отношению к корню. Например, вот хорошо сформированный XML документ, чей корень имеет пять дочерних узлов, включая элемент верхнего уровня:
<?xml-stylesheet href="mystyle.css" type="text/css"?>
<!-- this is a perfectly legitimate XML document -->
<top_level_element/>
Five? Похоже, что их всего три. Думаю, я позволю вам самим разобраться, что же такое остальные два. Подсказка: в этом примере может быть семь узлов.
Выражение XPath /
находит корень документа, а не элемент верхнего уровня. В приведенном выше случае для поиска элемента верхнего уровня используется /top_level_element
, или /*
. (Для поиска элемента верхнего уровня всегда безопасно использовать /*
, так как корень документа должен иметь дочерний элемент)
Так что, вооруженный этим знанием, давайте посмотрим, что делает applied-templates
. В основном он выполняет двухступенчатый процесс: Во-первых, он строит набор узлов. Затем, и для каждого из них, он находит соответствующий шаблон (из числа шаблонов в XSLT-файле) и применяет к нему этот шаблон. Как Вы заметили в одном из комментариев, он концептуально очень похож на цикл.
На первом этапе используется атрибут select
. Он предоставляет выражение XPath, которое используется для построения набора узлов, к которым будут применяться шаблоны. Если атрибут select
не указан, то строится список всех дочерних элементов контекстного узла. (Узел контекста - это узел, к которому применяется текущий шаблон)
Атрибут match
для элементов template
используется на втором этапе. Процессор таблиц стилей находит все шаблоны, атрибут которых совпадает с узлом, к которому он пытается применить шаблоны. Если он находит более одного, он выбирает наиболее конкретный, например, учитывая эти шаблоны:
<xsl:template match="*"/>
<xsl:template match="foo"/>
<xsl:template match="foo[bar]"/>
элемент foo
с дочерним элементом bar
будет соответствовать третьему, элемент foo
без элемента bar
будет соответствовать второму, а элемент baz
будет соответствовать первому. (Фактический метод, который использует XSLT, определен здесь ; на практике я использую XSLT уже почти десять лет, и мне ни разу не понадобилось конкретно знать, как он работает, хотя это интересно. )
Если он не найдет совпадение, то будет использовать встроенный шаблон по умолчанию для типа узла - в принципе, можно предположить, что любое преобразование XSLT неявно содержит эти шаблоны:
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
<xsl:copy/>
</xsl:template>
<xsl:template match="processing-instruction() | comment() | @*"/>
Вооружившись всеми этими знаниями, Вы можете теперь понять, что преобразование идентичности:
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
соответствует любому узлу или атрибуту (обратите внимание, что атрибуты не являются узлами, поэтому @*
необходимо), скопирует его, а затем применит шаблоны ко всем своим дочерним узлам и атрибутам. (Только корень документа и элементы будут иметь дочерние узлы, и только элементы будут иметь атрибуты). Поскольку это единственный шаблон в преобразовании, и он соответствует всем узлам и атрибутам, он применяется ко всем дочерним узлам и атрибутам. Таким образом, он копирует все, что находится в дереве исходных текстов, в дерево вывода.
Если добавить этот шаблон в идентификационное преобразование:
<xsl:template match="foo"/>
то теперь у Вас есть преобразование, которое копирует все узлы дерева исходных текстов кроме foo
элементов - этот второй шаблон совпадает с элементами foo
(первый тоже совпадает, но так как атрибут второго совпадает с
более специфичен, то это тот, который выбирает XSLT) и ничего с ними не делает.
Учитывая всё это, ответы на Ваши специфические вопросы:
применяет шаблоны к дочерним элементам контекстного узла.
Совпадающие элементы не "возвращаются" на шаге 1; процессор XSLT находит шаблон для каждого из них и применяет его.
В данном примере узел контекста - это корень документа, абстрактный узел, который элемент верхнего уровня и любые комментарии или инструкции по обработке вне него являются дочерними элементами.
попытается найти шаблон, соответствующий текущему узлу и его дочерним элементам.тело>
и