Книга: XSLT

Элемент

Элемент <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>.

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


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