=> Главная База Знаний Xslt Элемент <xsl:if>


Элемент <xsl:if>

Элемент <xsl:if>

При помощи элемента

<xsl:if>
осуществляются проверки условия и принимаются действия на основе результата проверки. Он во многом похож на оператор
if
в языках программирования. У элемента
<xsl:if>
один атрибут:

• 

test
(обязательный). Устанавливается в значение логического (
Boolean
,
true/false
) условия, которое вы хотите проверить.

Элемент заключает в себе тело шаблона.

Вот как это работает: вы включаете тело шаблона внутрь элемента

<xsl:if>
, проверяющего какое-то выражение. Если это выражение истинно, тело шаблона используется, если ложно — игнорируется:

<xsl:if test="expression">

 <!--template body-->

</xsl:if>

Можно проверять любое выражение XPath. Для преобразования его в значения

true/false
в элементе
<xsl:if>
применяйте следующие правила:

• если выражение вычисляется в набор узлов, оно трактуется как

true
, когда набор узлов содержит хотя бы один узел;

• выражение-строка считается

true
, если строка не пуста;

• фрагмент результирующего дерева трактуется как

true
, если содержит узлы;

• если результат выражения — число, он считается

true
, когда отличен от нуля.

Элемент

<xsl:if>
во многом похож на оператор
if-then
в языках программирования. Однако не существует оператора
<xsl:else>
для формирования конструкций
if-then-else
— для этого служит элемент
<xsl:choose>
.

В листинге 5.1 я перечисляю планеты в

planets.xml
одну за другой и добавляю горизонтальное правило HTML, элемент <HR> (horizontal rule), после последнего элемента — но только после последнего. При помощи
<xsl:if>
это можно сделать так.

Листинг 5.1. Применение <xsl:if>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

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

 <xsl:template match="PLANETS">

  <HTML>

   <HEAD>

    <TITLE>

     Planets

    </TITLE>

   </HEAD>

   <BODY>

    <xsl:apply-templates select="PLANET"/>

   </BODY>

  </HTML>

 </xsl:template>


 <xsl:template match="PLANET">

  <P>

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

   is planet number <xsl:value-of select="position()"/> from the sun.

  </P>

  <xsl:if test="position() = last()"><HR/><xsl:if>

 </xsl:template>

</xsl:stylesheet>

Вот результат — как видите, элемент <HR> появляется только после последней перечисленной планеты:

<HTML>

 <HEAD>

  <TITLE>

   Planets

  </TITLE>

 </HEAD>

 <BODY>

  <P>

   Mercury is planet number 1 from the sun.

  </P>

  <P>

   Venus is planet number 2 from the sun.

  </P>

  <P>

   Earth is planet number 3 from the sun.

  </P>

  <HR>

 </BODY>

</HTML>

Рассмотрим еще один пример — преобразование XML-XML, в котором перечисляются планеты из

planets.xml
. Однако я хочу, чтобы выводилось не просто «The first three planets are: Mercury Venus Earth» (первые три планеты: Меркурий Венера Земля), a «The first three planets are: Mercury, Venus, and Earth». Необходимые знаки пунктуации можно добавить, определяя текущий элемент при помощи функции
position
и проверяя позицию при помощи
<xsl:if>
(листинг 5.2).

Листинг 5.2. Второй пример применения <xsl:if>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

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

 <xsl:output method="xml"/>

 <xsl:template match="PLANETS">

  <DOCUMENT>

   <TITLE>

    The Planets

   </TITLE>

   <PLANETS>

    The first three planets are: <xsl:apply-templates select="PLANET"/>

   </PLANETS>

  </DOCUMENT>

 </xsl:template>


 <xsl:template match="PLANET">

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

  <xsl:if test="position()!=last()">, </xsl:if>

  <xsl:if test="position()=last()-1">and </xsl:if>

  <xsl:if test=position()=last()">.</xsl:if>

 </xsl:template>

</xsl:stylesheet>

Вот результат:

<?xml version=" 1.0" encoding="UTF-8"?>

<DOCUMENT>

 <TITLE>

  The Planets

 </TITLE>

 <PLANETS>

  The first three planets are: Mercury, Venus, and Earth

 </PLANETS>

</DOCUMENT>

Как видите, я смог добавить правильные знаки пунктуации, определяя место в документе при помощи

<xsl:if>
.

При помощи

<xsl:if>
можно также обнаруживать ошибки во время преобразования. Например, при помощи
<xsl:if>
можно вывести сообщение, есть ли в
planets.xml
элемент
<NAME>
(листинг 5.3).

Листинг 5.3. Обнаружение ошибок при помощи <xsl:if>

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"

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

 <xsl:output method="xml"/>

 <xsl:template match="PLANETS">

<DOCUMENT>

   <TITLE>

    The Planets

   </TITLE>

   <PLANETS>

    The first three planets are: <xsl:apply-templates select="PLANET"/>

   </PLANETS>

  </DOCUMENT>

 </xsl:template>


 <xsl:template match="PLANET">

  <xsl:if test="NAME[not(text())]">

   <xsl:message terminate="yes">

    Each planet must have a name!

   </xsl:message>

  </xsl:if>

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

  <xsl:if test="position()!=last()">. </xsl:if>

  <xsl:if test="position()=last()-1">and </xsl:if>

  <xsl:if test="position()=last()">.</xsl:if>

 </xsl:template>

</xsl:stylesheet>

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

<NAME>
пустым:

<?xml version="1.0"?>

<?xml-stylesheet type="text/xml" href="/planets.xsl"?>

<PLANETS>

 <PLANET>

  <NAME>Mercury</NAME>

  <MASS UNITS="(Earth = 1)">.0553</MASS>

  <DAY UNITS="days">58.65</DAY>

  <RADIUS UNITS="miles">1516</RADIUS>

  <DENSITY UNITS="(Earth = 1)">.983</DENSITY>

  <DISTANCE UNITS="million miles">43.4</DISTANCE><!--B перигелии-->

 </PLANET>

 <PLANET>

  <NAME></NAME>

  <MASS UNITS="(Earth = 1)">.815</MASS>

  <DAY UNITS="days">116.75</DAY>

  <RADIUS UNITS="miles">3716</RADIUS>

  <DENSITY UNITS="(Earth = 1)">.943</DENSITY>

  <DISTANCE UNITS="million miles">66.8</DISTANCE><!--B перигелии-->

 </PLANET>

 .

 .

 .

Вот как происходит обработка примера в Xalan:

C:\planets>java org.apache.xalan.xslt.Process -IN planets.xml -XSL errors.xsl -OUT new.xml

file:///C:/XSL/w.xsl: Line 18: Column 38: Each planet must have a name!

XSLT Error (javax.xml.transform.TransformerException): Stylesheet directed termination

Если вы знакомы с конструкцией

if
в языках программирования, вы знаете, что инструкция
if
обычно сопровождается инструкцией
else
, которая выполняется при ложности условия в
if
. Но в XSLT нет элемента
<xsl:else>
. Для задания альтернативных ветвей выполнения XSLT служит элемент
<xsl:choose>
.