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

На этом мы заканчиваем обсуждение возможных условий узлов в образцах шага. Третья и последняя часть образцов шага — предикаты

Образцы шага, часть 3: предикаты

Предикаты, третья часть образцов шага, содержат выражения XPath. Предикат можно заключить в операцию [] и проверить, верно ли заданное условие.

Например, можно проверить:

• значение атрибута в заданной строке;

• значение элемента;

• содержит ли элемент определенного ребенка, атрибут или другой элемент;

• позицию узла в дереве узлов.

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

Выражения XPath более сложны, чем образцы выбора. Если при их создании у вас возникнут затруднения, вам может помочь удобная программа-пример ApplyXPath.java из пакета Xalan, при помощи которой можно применить к документу выражение XPath и посмотреть на результаты. Например, если применить выражение XPath "PLANET/NAME" к planets.xml, будут отображены значения всех элементов <NAME>, дочерних по отношению к элементам <PLANET> (открывающий и закрывающий теги <output> добавляются программой ApplyXPath):

C:\>java ApplyXPath planets.xml PLANET/NAME

<output>

<NAME>Mercury</NAME>

<NAME>Venus</NAME>

<NAME>Earth</NAME>

</output>

Если предикат имеет числовое значение, последнее представляет условие позиции (position test). Например, NAME[1] выбирает первого ребенка <NAME> контекстного узла. Условия позиции W3C, а также условия позиции в Xalan, Oracle, XT, Saxon и MSXML3 (XML процессор от Microsoft, подразумевающий использование JavaScript, с которым вы встречались в главе 1 и еще встретитесь в главе 10, «Работа с API процессоров XSLT») основаны на 1, поэтому первый ребенок — это ребенок 1. Условия позиции в XML-документах, которые используют таблицы стилей XSL и загружаются в текущую версию Internet Explorer (версию 5.5, на смену которой приходит 6.0), основаны на 0 (и в предикатах можно использовать только очень сокращенную форму выражений XPath) — и, следовательно, так же считается в большей части документации по XSL на web-узле Microsoft. В другом случае значением предиката должна быть ложь или истина, что называется логическим условием (Boolean test). Например, предикат [@UNITS="million miles"] выбирает элементы, у которых имеются атрибуты UNITS со значением "million miles".

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

• когда образец используется в атрибуте match, предикат не должен содержать никаких ссылок на переменные XSL (которые обсуждаются в главе 9). Это ограничение не применяется к предикатам, используемым в элементах <xsclass="underline" number>;

• образцы не могут использовать в предикатах функцию XPath current, возвращающую текущий узел. Ее применение ограничено, поэтому обработка зависит от реализации и не зависит от текущего состояния обработки.

В следующем примере образец выбирает элементы <PLANET> с дочерними элементами <NAME>:

<xsclass="underline" template match="PLANET[NAME]">

 .

 .

 .

</xsclass="underline" template>

Этот образец выбирает любой элемент с дочерним элементом <NAME>:

<xsclass="underline" template match="*[NAME]">

 .

 .

 .

</xsclass="underline" template>

Теперь я задал элементам <PLANET> в planets.xml новый атрибут, COLOR, устанавливающий цвет планеты:

<?xml version="1.0"?>

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

<PLANETS>

 <PLANET COLOR="RED">

  <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><!--В перигелии-->

 </PLANET>

 <PLANET COLOR="WHITE">

  <NAME>Venus</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>

 <PLANET COLOR="BLUE">

  <NAME>Earth</NAME>

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

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

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

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

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

 </PLANET>

</PLANETS>

Следующее выражение выбирает элементы <PLANET> с атрибутом COLOR:

<xsclass="underline" template match="PLANET[@COLOR]">

 .

 .

 .

</xsclass="underline" template>

А что, если нам требуется выбрать планеты, у которых атрибут COLOR имеет значение "BLUE" (голубой)? Это можно сделать при помощи операции =, как показано в листинге 4.5.

Листинг 4.5. Применение операции =

<"xml version="1.0"?>

<xsclass="underline" stylesheet version="1.0"

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