Не могу перестать думать о XSLT в процедурном плане ... помогите с apply-templates - PullRequest
4 голосов
/ 02 декабря 2008

Я знаю, что XSLT не работает в процедурном плане, но, к сожалению, я слишком долго писал процедурные языки. Может ли кто-нибудь помочь мне, объяснив простым языком, как работают такие вещи, как apply-templates, и помогите толпе, как я, понять это.

Ответы [ 3 ]

5 голосов
/ 02 декабря 2008

С чего вы взяли, что процедурные условия здесь не применяются? Просто соглашение о вызовах несколько более неявное, чем вы обычно ожидаете, потому что в нем присутствует невидимый контекст. Все, что apply-templates делает, может быть выражено в процедурных терминах.

По сути, apply-templates - это не что иное, как цикл для каждого. Начиная с того места, где вы в данный момент находитесь в документе (контекст, подумайте «this»), он перебирает дочерние узлы.

Для каждого дочернего процесса процессор выбирает соответствующий xsl:template с наивысшим приоритетом (на основе их соответствующих атрибутов match и priority), устанавливает контекст для дочернего элемента и запускает этот шаблон (думаю, "function "). После возвращения шаблона контекст возвращается назад, и наступает следующий дочерний ход.

Даже когда все становится рекурсивным (чего довольно трудно избежать в XSLT), весь процесс действительно не становится более сложным. Контекстный «указатель» перемещается, а шаблоны вызываются.

Вы можете ограничить набор узлов, который повторяется apply-templates, используя атрибут select:

<!-- all children of the context node regardless -->
<xsl:apply-templates />  

<!-- all children of the context node being "data" with a @name of "Foo" -->
<xsl:apply-templates select="data[@name='Foo']" />  

Вы можете отсортировать набор узлов до итерации, если хотите:

<!-- all children of the context node being "data" with a @name of "Foo",
     ordered by their respective "detail" count -->
<xsl:apply-templates select="data[@name='Foo']"> 
  <xsl:sort select="count(detail)" data-type="number" order="descending"/>
</xsl:apply-templates>

И вы можете передавать параметры в свой шаблон, если вам нужно, так же, как вы это делаете с обычным вызовом функции:

<!-- pass in some parameter -->
<xsl:apply-templates select="data[@name='Foo']"> 
  <xsl:with-param name="DateSetIcon" select="$img_src" />
</xsl:apply-templates>

Вот и все, что нужно.

EDIT:

Я знаю, что последний комментарий немного провокационный. Это очень намеренно, для базового понимания того, как работает apply-templates, это более или менее так. Последствия и возможности, вытекающие из того факта, что не вы определяют, какой шаблон вызывать, а скорее позволяют процессору выбрать подходящий для вас, конечно, больше, чем то, на что это похоже на неподготовленное ухо. Декларативный / неявный подход всего этого, безусловно, требует некоторого времени, чтобы погрузиться.

5 голосов
/ 02 декабря 2008

Я написал запись в блоге давным-давно, которая показывает простую таблицу стилей, написанную в «процедурном» стиле, используя xsl:for-each и эквивалентный xsl:apply-templates. Это ни в коем случае не исчерпывающее руководство, но, надеюсь, оно будет полезным.

2 голосов
/ 02 декабря 2008

Я полностью согласен с ответом и сообщением в блоге Грега Бича.

Для более подробного сравнения <xsl:for-each> и <xsl:apply-templates> см. мой ответ на вопрос "xsl: for-each vs. xsl: apply-templates" в xsl -список и наслаждайся всей веткой .

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

Другое отличие от процедурного языка программирования состоит в том, что порядок, в котором будут применяться шаблоны, не предопределен. В чистом функциональном языке программирования нет понятия «состояние» или «порядок выполнения».

Ни XSLT 2.0 , ни XSLT 1.0 не указывает какой-либо определенный порядок применения выбранных правил шаблона - только то, что их результаты будут объединять в соответствии с порядком узлов (в отсортированной последовательности, если есть какие-либо директивы <xsl:sort> или иным образом в порядке документов узлов), к которым применяются шаблоны.

XSLT 2.0 Spec говорит:

" Каждое оцениваемое правило шаблона создает последовательность элементов в качестве своего результата. Результирующие последовательности (по одной для каждого узла в отсортированной последовательности) затем объединяются, образуя одну последовательность. Они объединяются, сохраняя порядок узлов в отсортированной последовательности. Окончательная каскадная последовательность образует результат инструкции xsl: apply-templates"

XSLT 1.0 спецификация гласит:

" Реализации могут обрабатывать исходный документ любым способом, который дает тот же результат, как если бы он был обработан с использованием этой модели обработки ."

Возможно даже, что реализация XSLT может применять шаблоны (или тело <xsl:for-each>) параллельно.

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