Мне нравится твой вопрос. Ты очень ясно говоришь о том, чего еще не понимаешь. Вам просто нужно что-то связать вещи. Я рекомендую вам прочитать «Как работает XSLT» , главу, которую я написал, чтобы точно ответить на ваши вопросы. Я хотел бы услышать, если это связывает вещи для вас.
Менее формально, я постараюсь ответить на каждый ваш вопрос.
- В каком порядке выполняются шаблоны, и
- Когда они выполняются, совпадают ли они с (а) исходным XML-кодом или (б)
текущий выход XSLT к этому
точка
В любой заданной точке обработки XSLT существуют, в некотором смысле, два контекста, которые вы определяете как (a) и (b): где вы находитесь в исходном дереве и где вы находятся в дереве результатов . То, где вы находитесь в исходном дереве, называется текущим узлом . Он может меняться и перемещаться по всему исходному дереву, поскольку вы выбираете произвольные наборы узлов для обработки с использованием XPath. Однако концептуально вы никогда не «перепрыгиваете» результирующее дерево одним и тем же способом. Процессор XSLT конструирует его упорядоченно; сначала он создает корневой узел дерева результатов; затем он добавляет дочерние элементы, формируя результат в порядке документа (сначала в глубину). [Ваш пост побуждает меня снова взять мою программную визуализацию для экспериментов XSLT ...]
Порядок шаблонных правил в таблице стилей никогда не имеет значения. Вы не можете определить, просто взглянув на таблицу стилей, в каком порядке будут создаваться правила шаблона, сколько раз будет создаваться правило или даже будет ли оно вообще. (match="/"
является исключением; вы всегда можете знать, что оно сработает.)
Я предполагаю, что шаблон № 1 будет
выполнить первым. Я не знаю почему
Предположим, это - это только потому, что это
появляется первым в документе?
Неа. Он будет вызван первым, даже если вы поместите его последним в документе. Порядок правил шаблона никогда не имеет значения (за исключением случая ошибки, когда у вас более одного правила шаблона с одинаковым приоритетом, совпадающим с одним и тем же узлом; даже в этом случае это не обязательно для разработчика, и вы никогда не должны полагаться на такое поведение). Сначала его вызывают, потому что первое, что всегда происходит, когда вы запускаете процессор XSLT, - это виртуальный вызов <xsl:apply-templates select="/"/>
. Один виртуальный вызов создает все дерево результатов. Ничего не происходит вне этого. Вы можете настроить или «настроить» поведение этой инструкции, определив правила шаблона.
Будет ли выполнен шаблон №2? Это соответствует узлу в исходном XML, но
к тому времени мы доберемся до этого
шаблон (при условии, что он работает вторым),
узел "firstName" не будет в
дерево вывода.
Шаблон № 2 (или любые другие правила шаблонов) никогда не сработает, если у вас нет <xsl:apply-templates/>
вызова где-то в правиле match="/"
. Если у вас их нет, то никакие правила шаблона, кроме match="/"
, не сработают. Подумайте об этом так: чтобы сработало шаблонное правило, оно не может просто соответствовать узлу во входных данных. Он должен соответствовать узлу, который вы выбрали для процесса (используя <xsl:apply-templates/>
). И наоборот, он будет соответствовать узлу столько раз, сколько вы захотите обработать.
Будет [* match="/"
шаблон] опережает все остальные шаблоны
от выполнения, так как нет ничего
чтобы соответствовать после этого первого шаблона
завершено?
Это правило вытесняет все остальное никуда, включая <xsl:apply-templates/>
. Есть еще много узлов, которые могут быть обработаны в исходном дереве. Они всегда все там, созрели для сбора; обрабатывать каждый столько раз, сколько вы хотите. Но единственный способ обработать их, используя шаблонные правила, это вызвать <xsl:apply-templates/>
.
К этому моменту я был обеспокоен
с более поздними шаблонами, не выполняющимися
потому что узлы они работали
не отображаются на выходе, но
как насчет обратного? Может«ранее» шаблон создает узел, который
«поздний» шаблон может что-то сделать
с
Дело не в том, что «более ранний» шаблон создает новый узел для обработки; Дело в том, что «более ранний» шаблон в свою очередь обрабатывает больше узлов из исходного дерева, используя ту же инструкцию (<xsl:apply-templates
). Вы можете думать об этом как о рекурсивном вызове одной и той же «функции» с разными параметрами каждый раз (узлы для обработки, определенные контекстом и атрибутом select
).
В итоге получается древовидный стек рекурсивных вызовов одной и той же «функции» (<xsl:apply-templates>
). И эта древовидная структура изоморфна вашему реальному результату. Не все осознают это или думают об этом таким образом; это потому, что у нас нет эффективных инструментов визуализации ... пока.
Шаблон # 1 создает новый узел с именем
"ФИО". Шаблон № 2 соответствует
тот же самый узел. Будет шаблон № 2
выполнить, потому что узел "fullName"
существует на выходе к тому времени, когда мы
перейти к шаблону № 2?
Неа. Единственный способ сделать цепочку обработки - это явно настроить ее таким образом. Создайте переменную, например, $tempTree
, которая содержит новый элемент <fullName>
, а затем обработайте it , например, <xsl:apply-templates select="$tempTree">
. Чтобы сделать это в XSLT 1.0, вам нужно обернуть ссылку на переменную функцией расширения (например, exsl:node-set()
), но в XSLT 2.0 она будет работать так же, как есть.
Независимо от того, обрабатываете ли вы узлы из исходного исходного дерева или из создаваемого вами временного дерева, в любом случае вам нужно явно указать, какие узлы вы хотите обработать.
Мы не рассмотрели, как XSLT получает все свое неявное поведение. Вы также должны понимать встроенный шаблон правил . Я все время пишу таблицы стилей, которые даже не содержат явного правила для корневого узла (match="/"
). Вместо этого я полагаюсь на встроенное правило для корневых узлов (применять шаблоны к дочерним элементам), которое совпадает со встроенным правилом для узлов элементов. Таким образом, я могу игнорировать большие части входных данных, позволить процессору XSLT автоматически проходить через него, и только когда он встретит интересующий меня узел, я сделаю что-то особенное. Или я мог бы написать единственное правило, которое копирует все рекурсивно (называемое преобразованием идентичности), переопределяя его только там, где это необходимо, для внесения постепенных изменений во входные данные. После того, как вы прочитали «Как работает XSLT», ваше следующее задание - найти «преобразование идентичности».
Я понимаю, что я глубоко невежественен
о "дзен" XSLT. На сегодняшний день мой
таблицы стилей состояли из
шаблон, соответствующий корневому узлу, затем
полностью процедурные оттуда.
Я устал от этого. я мог бы
скорее на самом деле понимаю XSLT
правильно, отсюда и мой вопрос.
Я аплодирую вам. Теперь пришло время принять «красную таблетку»: прочитайте «Как работает XSLT»