Различия между for-each и шаблонами в xsl?
Оба xsl:for-each
и xsl:template
используются для извлечения узлов из xml в таблице стилей xsl. Но в чем принципиальное отличие между ними? Пожалуйста, направляйте меня. Спасибо заранее.
Ответы
Ответ 1
Я думаю, что это имеет какое-то отношение к пониманию push vs. pull, чем просто сравнение xsl:for-each
или xsl:template match="..."
. Вы часто видите программистов из другой дисциплины, используя множество xsl:if
, xsl:choose
и for-loops, когда проблема может быть решена более элегантным способом XSLTish.
Но на вопрос: На мой взгляд, если вы решили использовать xsl:for-each
вместо обработки данных с помощью xsl:apply-templates
, вам нужно переосмыслить. Бывают случаи, когда for-loop подходит для XSLT, но всякий раз, когда соответствующий шаблон будет делать то же самое, шаблоны - это путь. По моему опыту, вы обычно можете сделать большинство xsl:for-each
с помощью xsl:apply-templates
.
Некоторые преимущества, которые я вижу в использовании совпадающих шаблонов над циклом for, заключаются в следующем:
- Таблицы стилей проще поддерживать и расширять, особенно если исходные данные изменяются.
- Как упоминает @chiborg, шаблоны могут быть повторно использованы, поскольку они не встроены в конкретный шаблон. Вместе с
xsl:next-match
в XSLT 2.0 вы можете цепочки шаблонов вместе мощными способами.
- Вам не нужно имитировать поведение, уже встроенное для всех XSLT-процессоров; используйте
xsl:apply-templates
и пусть процессор работает для вас.
- Также мне легче понять и отладить таблицу стилей стиля push. Если вы разделите свои таблицы стилей небольшими шаблонами, которые делают одно или несколько вещей и записывают конкретные шаблоны соответствия, легко увидеть, какой шаблон выполняет что-то и отслеживать источник проблемы.
Ответ 2
Я согласен с другими ответами, но я скажу, что, по моему опыту, таблица стилей, написанная с помощью xsl:for-each
, может быть намного легче читать, понимать и поддерживать, чем та, которая сильно зависит от xsl:apply-templates
... Особенно xsl:apply-templates
с неявным выбором (или очень общим выбором, например select="node()"
).
Почему? Потому что очень легко увидеть, что будет делать каждый. С применением шаблонов вы, по сути, должны (а) знать обо всех возможных входах XML (что будет проще, если у вас есть схема, но тогда вам все равно придется переваривать схему, и много раз у вас нет схемы, особенно для промежуточных промежуточных XML-данных, отправленных на одном этапе конвейера, и даже если у вас есть схема, ваша инфраструктура разработки (например, ESB или CMS) может не дать вам возможности проверить ваш XML в каждой точке вашего конвейера. Поэтому, если недействительные данные ползут в вас, вас не будут уведомлять сразу), поэтому вы можете предсказать, какие типы узлов будут выбраны (например, дети контекста node); и (б) просмотрите каждый шаблон в таблице стилей, чтобы увидеть, какой шаблон соответствует тем узлам с наивысшим приоритетом (и последний в порядке документа). Порядок обработки также может пропускаться по всем файлам или по разным файлам (импортированным или включенным). Это может сделать очень трудным "увидеть", что происходит.
В то время как для каждого из них вы точно знаете, какой код будет создан: код внутри каждого для каждого. И поскольку for-each требует явного выражения select, у вас, скорее всего, будет более узкое поле для определения того, какие узлы могут быть сопоставлены.
Теперь я не отрицаю, что apply-templates намного более мощные и гибкие, чем для каждого. Точно так: конструкции, которые являются более мощными и гибкими, также сложнее сдерживать, понимать и отлаживать (и предотвращать дыры в безопасности). Это правило наименьшей мощности: "Мощные языки (или в этом случае, конструкции) препятствуют повторному использованию информации". (Также обсуждается здесь.)
При использовании шаблонов apply-template каждый шаблон более модульный и, следовательно, более многоразовый сам по себе, но таблица стилей более сложна и взаимодействие между шаблонами меньше
предсказуемы. Когда вы используете для каждого, поток обработки легко предсказать и увидеть.
С <xsl:apply-templates />
(или с <xsl:for-each select="node()"/>
), когда изменяется структура входного XML, поведение таблицы стилей изменяется без проверки разработчика. Является ли это хорошим или плохим, зависит от того, сколько предусмотрительности вы вложили в таблицу стилей и насколько хорошая связь между разработчиком XML-схемы и разработчиком стилей (кто может быть одним и тем же лицом или может принадлежать к различным организациям).
Так что для меня это решение. Если у вас есть документ-ориентированный XML, например HTML, где многие типы элементов действительно могут иметь много разных типов детей, в иерархии произвольной глубины и обработка определенного типа элемента не очень часто зависит от его контекста, то применять шаблоны абсолютно необходимо. С другой стороны, если у вас есть "ориентированный на данные" XML, с предсказуемой структурой, где вы не часто имеете один и тот же тип элемента, что означает одно и то же в разных контекстах, для каждого из них может быть гораздо проще читать и отлаживать (и поэтому писать правильно и быстро).
Ответ 3
Оба "для каждого" и "шаблон" используется для извлечения узлов из xml в xsl. Но в чем разница между ними в основном
Вот некоторые из наиболее важных отличий:
-
xsl:apply-templates
намного богаче и глубже, чем xsl:for-each
, даже
просто потому, что мы не знаем, какой код будет применяться на узлах
выбор - в общем случае этот код будет отличаться для
различные узлы списка node.
-
Код, который будет применяться
может быть записано после записи xsl:apply template
и
люди, которые не знают оригинального автора.
библиотека FXSL реализация функций более высокого порядка (HOF) в XSLT невозможна, если XSLT не было инструкции <xsl:apply-templates>
.
Резюме. Шаблоны и инструкция <xsl:apply-templates>
- это то, как XSLT реализует и обрабатывает полиморфизм.
Ссылка. Смотрите эту цепочку: http://www.stylusstudio.com/xsllist/200411/post60540.html
Ответ 4
Это не имеет большого значения, но вы можете подумать об этом для следующих правил, которые я нашел:
- Если код зависит от контекста
position (position()), поместите его в
<xsl:for-each>
.
- Если код зависит от контекста
node (или любой путь местоположения), поставьте его
в соответствующем шаблоне.
- В противном случае используйте именованный шаблон.
Ссылка и дополнительная информация:
http://www.jenitennison.com/blog/node/9
Ответ 5
for-each
может использоваться только в одном месте вашего шаблона. Шаблоны можно повторно использовать с различными вызовами apply-templates
. Я в основном использую шаблоны вместо каждого из них из-за дополнительной гибкости.
Ответ 6
Они предназначены для выполнения различных инструкций XSLT.
Больше, чем стиль push и pull, это больше похоже на итерацию против рекурсии.
xsl:for-each
является инструкцией итератора со всеми преимуществами и ограничениями итерации в декларативной парадигме безстоящих состояний: хороший процессор не должен опрашивать стек вызовов.
xsl:apply-templates
является общей инструкцией рекурсии. Общее в том смысле, что оно более мощное, чем xsl:call-template
: вы "бросаете" выбранные узлы в механизм сопоставления шаблонов, поистине "вызов динамической функции".
Ответ 7
Одно использование for-each
Я не видел: вы можете использовать его для переключения контекста node на другой документ. Я использовал его для преобразования XML данных в форму ввода HTML. Шаблон, который соответствует полю данных, содержал для каждого, который выбрал один node: xs:element
в XSD, который описывал преобразованное поле данных.
Используя описание в XSD, одно поле данных может быть преобразовано в группу переключателей, выпадающее поле или простой и простой ввод текста. Без for-each
я не мог пройти через два документа одновременно.
В общем, я предпочитаю сопоставлять шаблоны. Я нахожу, что это соответствует понятию одного преобразования, примененного сразу лучше, чем для каждого из этих node, затем следующего, затем одного после этого и т.д. Но это личное предпочтение, конечно.