Различия между для каждого и шаблоны в XSL? - PullRequest
16 голосов
/ 16 декабря 2010

И xsl:for-each, и xsl:template используются для извлечения узлов из xml в таблице стилей xsl.Но в чем принципиальная разница между ними?Пожалуйста, ведите меня.Заранее спасибо.

Ответы [ 7 ]

12 голосов
/ 16 декабря 2010

Я в целом согласен с другими ответами, но скажу, что по моему опыту, таблица стилей, написанная с xsl:for-each, может быть намного легче читать, понимать и поддерживать, чем та, которая сильно зависит от xsl:apply-templates ...Особенно xsl:apply-templates с неявным выбором (или очень общим выбором, например select="node()").

Почему?Потому что очень легко увидеть, что сделает каждый.С apply-templates вы по сути должны (а) знать обо всех возможных входах XML (что будет проще, если у вас есть схема, но тогда вам все равно придется переваривать схему; и во многих случаях у вас нет схемыособенно для переходных промежуточных данных XML, отправляемых на одном этапе конвейера, и даже если у вас есть схема, ваша среда разработки (например, ESB или CMS) может не дать вам способа проверить ваш XML в каждой точке конвейера.Таким образом, если в вас закрадываются недействительные данные, вы не будете сразу уведомлены), так что вы можете предсказать, какие типы узлов будут выбраны (например, дочерние элементы контекстного узла);и (b) просмотреть каждый шаблон в таблице стилей, чтобы увидеть, какой шаблон соответствует тем узлам с наивысшим приоритетом (и последним в порядке документов).Порядок обработки может также пропустить все файлы или другие файлы (импортированные или включенные).Это может сделать очень трудным «увидеть», что происходит.

Принимая во внимание, что для каждого вы точно знаете, какой код будет создан: код внутри для каждого.А поскольку для for-each требуется явное выражение select, у вас, скорее всего, будет более узкое поле для определения того, какие узлы могут быть сопоставлены.

Теперь я не отрицаю, что apply-templates намного большемощный и гибкий, чем для каждого.В том-то и дело: конструкции, которые являются более мощными и гибкими, также сложнее ограничивать, понимать и отлаживать (и предотвращать дыры в безопасности).Это правило наименьшей мощности : «Мощные языки (или в данном случае конструкции) запрещают повторное использование информации».( Также обсуждается здесь .)

Когда вы используете apply-templates, каждый шаблон является более модульным и, следовательно, более пригодным для повторного использования, но таблица стилей более сложна, и взаимодействие между шаблонами меньшепредсказуемы.Когда вы используете for-each, поток обработки легко предсказать и увидеть.

С <xsl:apply-templates />, (или с <xsl:for-each select="node()"/>), когда изменяется структура входного XML, поведение таблицы стилейизменения, без обзора разработчика.Хорошо это или плохо, зависит от того, сколько внимания вы вложили в свою таблицу стилей и насколько хорошо существует связь между разработчиком схемы XML и разработчиком таблицы стилей (который может быть одним и тем же лицом или принадлежать к разным организациям).

Так что для меня это призывный суд.Если у вас есть документно-ориентированный XML, такой как HTML, где у многих типов элементов действительно может быть много разных типов потомков в иерархии произвольной глубины, и обработка данного типа элемента не очень часто зависит от его контекста, тогда применять-шаблоны абсолютно необходимо.С другой стороны, если у вас есть «ориентированный на данные» XML с предсказуемой структурой, где у вас не часто есть один и тот же тип элемента, означающий одно и то же в разных контекстах, for-each может быть намного проще для чтения и отладки(и поэтому писать правильно и быстро).

7 голосов
/ 16 декабря 2010

Я думаю, что это имеет некоторое отношение к пониманию обработки стиля push vs. pull , а не просто к сравнению xsl:for-each или xsl:template match="...". Вы часто видите программистов из другой дисциплины, использующих множество xsl:if, xsl:choose и циклов for, когда проблему можно было бы решить более элегантным способом XSLTish.

Но на вопрос: По моему мнению , если вы планируете использовать xsl:for-each вместо обработки данных с помощью xsl:apply-templates, вам нужно переосмыслить. Есть случаи, когда цикл for подходит в XSLT, но всякий раз, когда соответствующий шаблон делает то же самое, шаблоны - это путь. По моему опыту, вы можете сделать большинство xsl:for-each вместо xsl:apply-templates.

Некоторые преимущества использования соответствующих шаблонов для цикла for, как мне кажется, следующие:

  • Таблицы стилей легче поддерживать и расширять, особенно если исходные данные изменяются.
  • Как упоминает @chiborg, шаблоны можно использовать повторно, поскольку они не встроены в конкретный шаблон. Вместе с xsl:next-match в XSLT 2.0 вы можете мощно объединять шаблоны вместе.
  • Вам не нужно имитировать поведение, уже встроенное во все процессоры XSLT, то есть; используйте xsl:apply-templates и позвольте процессору работать на вас.
  • Кроме того, мне легче понять и отладить таблицу стилей push. Если вы разделите информацию в таблице стилей на небольшие шаблоны, которые выполняют одну или несколько задач и напишут конкретные шаблоны соответствия, легко увидеть, какой шаблон делает, и отследить источник проблемы.
5 голосов
/ 16 декабря 2010

И «for-each», и «template» используются для извлечения узлов из xml в xsl.Но в чем разница между ними в основном

Вот некоторые из наиболее важных различий :

  1. xsl:apply-templates намного богаче и глубже, чем xsl:for-each, даже просто потому, что мы не знаем, какой код будет применен к узлам выбора - в общем случае этот код будет отличаться для разных узлов узла-список.

  2. Код, который будет применяться, может быть написан способом после того, как xsl:apply template s был написан , и людьми, которые не знают первоначального автора.

В библиотеке FXSL * реализация функций высшего порядка (HOF) в XSLT была бы невозможна , если бы XSLT не имел <xsl:apply-templates> инструкция.

Сводка : Шаблоны и инструкция <xsl:apply-templates> - это то, как XSLT реализует и работает с полиморфизмом.

Ссылка : См. Этовся нить: http://www.stylusstudio.com/xsllist/200411/post60540.html

3 голосов
/ 16 декабря 2010

Это на самом деле не имеет значения, но вы можете подумать об этом для следующего большого пальца правил, которые я нашел:

  • Если код зависит от положения контекста (position ()), поместите его в <xsl:for-each>.
  • Если код зависит от узла контекста (или любого пути расположения), поместите его в соответствующий шаблон.
  • В противном случае используйте именованный шаблон.

Ссылка и перевод на: http://www.jenitennison.com/blog/node/9

2 голосов
/ 16 декабря 2010

Они предназначены для выполнения различных инструкций XSLT.

Больше, чем стиль push-pull, это больше похоже на итерацию или рекурсию.

xsl:for-each - это инструкция итератора со всемиПреимущества и ограничения итерации в декларативной парадигме без сохранения состояния: хороший процессор не должен ограничивать стек вызовов.

xsl:apply-templates - это общая инструкция рекурсии.Общее в том смысле, что оно более мощное, чем xsl:call-template: вы «выбрасываете» выбранные узлы в механизм сопоставления с образцом, поистине «динамический вызов функции».

1 голос
/ 17 декабря 2010

Одно использование for-each Я не видел упомянутого: вы можете использовать его для переключения узла контекста на другой документ. Я использовал его для преобразования данных XML в форму ввода HTML. Шаблон, который соответствовал полю данных, содержал для каждого, который выбрал один узел: xs:element в XSD, который описывал поле данных для преобразования.

Используя описание в XSD, одно поле данных может быть преобразовано в группу переключателей, раскрывающийся список или простой и простой текстовый ввод. Без for-each я не смог бы пройтись по двум документам одновременно.

В общем, я предпочитаю соответствующие шаблоны. Я считаю, что оно соответствует понятию единственного преобразования, применяемого одновременно лучше, чем для каждого этого узла, затем следующего, затем следующего и т. Д. Но это, конечно, личное предпочтение.

1 голос
/ 16 декабря 2010

for-each можно использовать только в одном месте вашего шаблона.Шаблоны могут быть повторно использованы с различными apply-templates вызовами.В основном я использую шаблоны вместо for-each из-за дополнительной гибкости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...