Выбрать главу

Можно выделить четыре основные задачи, для которых в преобразованиях используются выражения:

□ выбор узлов для обработки;

□ описание условий;

□ вычисление строковых значений, которые затем будут использованы в выходящем дереве;

□ вычисление множеств узлов, которые затем будут использованы в выходящем дереве.

Первая из задач непосредственно относится к самому процессу преобразования. Выражения, содержащиеся в атрибутах select элементов xsclass="underline" apply-templates и xsclass="underline" for-each, вычисляют множества, к узлам которых нужно применить шаблоны.

Пример
Листинг 3.16

<xsclass="underline" template match="HTML">

 <html>

  <xsclass="underline" apply-templates select="HEAD"/>

  <xsclass="underline" apply-templates select="BODY"/>

 </html>

</xsclass="underline" template>

В этом шаблонном правиле содержатся два элемента xsclass="underline" apply-templates, которые применяют шаблоны к множествам, выбранным выражениями HEAD и BODY соответственно.

Логические выражения XPath могут использоваться в качестве условий в таких элементах, как xsclass="underline" if и xsclass="underline" when, обеспечивая условную обработку.

Пример

Предположим, что нам нужно выводить различные сообщения в зависимости от возрастной информации, присутствующей во входящем документе:

Листинг 3.17. Входящий документ

<person>

 <name>Johnny</name>

 <age>19</age>

</person>

Листинг 3.18. Преобразование

<xsclass="underline" stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsclass="underline" template match="person">

  <xsclass="underline" if test="age &gt;= 21">

   <xsclass="underline" text>Welcome, </xsclass="underline" text>

   <xsclass="underline" value-of select="name"/>

   <xsclass="underline" text>.</xsclass="underline" text>

  </xsclass="underline" if>

  <xsclass="underline" if test="age &lt; 21">

   <xsclass="underline" text>Sorry, </xsclass="underline" text>

   <xsclass="underline" value-of select="name"/>

   <xsclass="underline" text>, access denied.</xsclass="underline" text>

  </xsclass="underline" if>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Выделенные выражения age >= 21 и age < 21 (сущности &gt; и &lt; обозначают символы "<", и ">") определяют условия: содержимое первого элемента xsclass="underline" if будет выполняться, только если значение элемента age было не меньше 21; содержимое второго — только если значение age было строго меньше 21. Этот же самый шаблон может быть переписан с использованием элементов xsclass="underline" choose, xsclass="underline" when и xsclass="underline" otherwise.

Листинг 3.19

<xsclass="underline" stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsclass="underline" template match="person">

  <xsclass="underline" choose>

   <xsclass="underline" when test="age &gt;= 21">

    <xsclass="underline" text>Welcome, </xsclass="underline" text>

    <xsclass="underline" value-of select="name"/>

    <xsclass="underline" text>.</xsclass="underline" text>

   </xsclass="underline" when>

   <xsclass="underline" otherwise>

    <xsclass="underline" text>Sorry, </xsclass="underline" text>

    <xsclass="underline" value-of select="name"/>

    <xsclass="underline" text>, access denied.</xsclass="underline" text>

   </xsclass="underline" otherwise>

  </xsclass="underline" choose>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Результатом этого преобразования будет текст

Sorry, Johnny, access denied.

В этой строке имя johnny было заимствовано из входящего документа. Оно было создано элементом xsclass="underline" value-of:

<xsclass="underline" value-of select="name"/>

Этот элемент вычислил значение выражения name, которое было указано в его атрибуте select, преобразовал результат вычисления в строку и создал в выходящем документе текстовый узел, содержащий вычисленное значение.

В данном случае выражение name использовалось для генерации символьных данных. Между тем, выражения вполне пригодны и для того, чтобы создавать в выходящем документе целые фрагменты:

Листинг 3.20. Преобразование

<xsclass="underline" stylesheet

 version="1.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsclass="underline" template match="person">

  <xsclass="underline" choose>

   <xsclass="underline" when test="age &gt;= 21">

    <event type="access granted">

     <xsclass="underline" copy-of select="name"/>

    </event>

   </xsclass="underline" when>

   <xsclass="underline" otherwise>

    <event type="access denied">

     <xsclass="underline" copy-of select="name"/>

     <reason type="underaged">

      <xsclass="underline" copy-of select="age"/>

     </reason>

    </event>

   </xsclass="underline" otherwise>

  </xsclass="underline" choose>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Листинг 3.21. Выходящий документ

<event type="access denied">

 <name>John</name>

 <reason type="underaged">

  <age>19</age>

 </reason>

</event>

Элемент xsclass="underline" copy-of, который использовался в этом преобразовании, делает примерно то же самое, что и xsclass="underline" value-of — вычисляет значение выражения и включает его в дерево выходящего документа. Главным отличием xsclass="underline" copy-of является то, что при его выполнении вычисленное выражение не преобразуется в строку, что позволяет копировать в выходящее дерево множества узлов и результирующие фрагменты. В приведенном выше примере элементы name и age выходящего документа являются копиями элементов name и age входящего документа.

В преобразованиях выражения могут использоваться только в атрибутах элементов и никогда — в тексте самого преобразования. Элемент

<reason type="underaged">

 age

</reason>

будет скопирован в выходящий документ, содержащий текст "age". Ни о каком вычислении выражения age речь, конечно же, не идет. Для того чтобы в результирующий документ был скопирован результат вычисления выражения, оно должно быть заключено в атрибут одного из вычисляющих элементов, например, xsclass="underline" copy-of: