Различия между 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, затем следующего, затем одного после этого и т.д. Но это личное предпочтение, конечно.