Книга: Технология XSLT

Выражения

Многие из задач, которые, так или иначе, выполняются во время преобразования, связаны с вычислением выражений. Для этих целей в XSLT используется язык XPath, который помимо выбора множеств узлов дерева может также выполнять некоторые основные операции над данными.

Замечание

Несмотря на то, что XPath является самостоятельным языком, его роль в XSLT настолько велика, что здесь и далее мы будем рассматривать их как единое целое.

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

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

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

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

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

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

Пример

Листинг 3.16

<xsl:template match="HTML">
 <html>
  <xsl:apply-templates select="HEAD"/>
  <xsl:apply-templates select="BODY"/>
 </html>
</xsl:template>

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

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

Пример

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

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

<person>
 <name>Johnny</name>
 <age>19</age>
</person>

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

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="person">
  <xsl:if test="age &gt;= 21">
   <xsl:text>Welcome, </xsl:text>
   <xsl:value-of select="name"/>
   <xsl:text>.</xsl:text>
  </xsl:if>
  <xsl:if test="age &lt; 21">
   <xsl:text>Sorry, </xsl:text>
   <xsl:value-of select="name"/>
   <xsl:text>, access denied.</xsl:text>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

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

Листинг 3.19

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="person">
  <xsl:choose>
   <xsl:when test="age &gt;= 21">
    <xsl:text>Welcome, </xsl:text>
    <xsl:value-of select="name"/>
    <xsl:text>.</xsl:text>
   </xsl:when>
   <xsl:otherwise>
    <xsl:text>Sorry, </xsl:text>
    <xsl:value-of select="name"/>
    <xsl:text>, access denied.</xsl:text>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

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

Sorry, Johnny, access denied.

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

<xsl:value-of select="name"/>

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

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

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

<xsl:stylesheet
 version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="person">
  <xsl:choose>
   <xsl:when test="age &gt;= 21">
    <event type="access granted">
     <xsl:copy-of select="name"/>
    </event>
   </xsl:when>
   <xsl:otherwise>
    <event type="access denied">
     <xsl:copy-of select="name"/>
     <reason type="underaged">
      <xsl:copy-of select="age"/>
     </reason>
    </event>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

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

<event type="access denied">
 <name>John</name>
 <reason type="underaged">
  <age>19</age>
 </reason>
</event>

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

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

<reason type="underaged">
 age
</reason>

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

<reason type="underaged">
 <xsl:copy-of select="age"/>
</reason>

В этом случае в элемент reason будет включен результат вычисления выражения age.

Оглавление книги


Генерация: 0.037. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз