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

  <MASS>

   Very heavy!

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

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

Сокращенный синтаксис

Для образцов существует два правила сокращения осей:

• child::childname может быть сокращено как childname;

• attribute::childname может быть сокращено как @childname.

В следующем списке перечислен ряд примеров образцов с сокращенным синтаксисом; в конце главы вы увидите много других.

• PLANET. Выбирает дочерние элементы <PLANET> контекстного узла;

• *. Выбирает все дочерние элементы контекстного узла;

• @UNITS. Выбирает атрибут UNITS узла;

• @*. Выбирает все атрибуты контекстного узла;

• */PLANET. Выбирает всех внуков <PLANET> контекстного узла;

• //PLANET. Выбирает всех потомков <PLANET> корня документа;

• PLANETS//PLANET. Выбирает все элементы <PLANET>, являющиеся потомками дочерних элементов <PLANETS> контекстного узла;

• //PLANET/NAME. Выбирает все элементы <NAME>, дочерние по отношению к <PLANET>;

• PLANET[NAME]. Выбирает детей <PLANET> контекстного узла, у которых есть дочерние элементы <NAME>.

В таком образце, как "child::PLANET", "child" является осью, a "PLANET" — условием узла, что представляет собой вторую часть образцов шага.

Образцы шага, часть 2: условия узла

Условия узла (node test) составляют вторую часть образцов шага. В качестве условий узла можно использовать названия узлов или символ подстановки * для выбора и узлов, и их типов. Например, выражение child::*/child::NAME выбирает все элементы <NAME>, являющиеся правнуками контекстного узла.

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

• comment() выбирает узлы комментария;

• node() выбирает узел любого типа;

• processing-instruction() выбирает узел инструкции обработки. В скобках можно указать название выбираемой инструкции обработки;

• text() выбирает текстовый узел.

В следующих разделах мы изучим эти условия узлов и рассмотрим примеры их применения.

Выбор комментариев

Текст комментариев можно выбрать при помощи образца comment(). Разумеется, не следует хранить данные, которые попадут в выходной документ, в комментариях входного документа. Тем не менее, вам может потребоваться преобразовать комментарии из формы <!--comment--> в какую-то другую форму, используемую другим языком разметки, — например, элемент <COMMENT>.

В следующем примере я извлеку комментарии из planet.xml и включу их в полученные выходные данные.

<PLANET>

 <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>

Чтобы извлечь комментарии и поместить их в элементы <COMMENT>, я включил правило только для комментариев (листинг 4.3).

Листинг 4.3. Выбор комментариев

<?xml version="1.0"?>

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

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

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

  <HTML>

   <xsclass="underline" apply-templates/>

  </HTML>

 </xsclass="underline" template>

 <xsclass="underline" template match="comment()">

  <COMMENT>

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

  </COMMENT>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

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

Venus

.815

116.75

3716

.943

66.8<COMMENT>B перигелии</СОММЕNT>

Обратите внимание: здесь текст для других элементов в элементе <PLANET> также включается в выходной документ, потому что так установлено в соответствии с правилом по умолчанию для каждого элемента. Поскольку для элементов я не предоставил какого-либо правила, их текст просто включается в выходной документ.

Выбор узлов при помощи node()

В образце условие узла node выбирает любой узел, за исключением корневого узла — помните, что в действительности это child::node(). Предположим, мы хотим создать таблицу стилей, копирующую произвольный документ XML, используя <xsclass="underline" copy>. (В главе 3 для этого применялся элемент <xsclass="underline" copy-of>.) Можно начать так, как показано в следующем примере. В этом случае в применяемом шаблоне для выбора любого элемента или любого атрибута используется операция OR, с которой мы познакомимся позже в этой главе (этот шаблон фактически выбирает себя — для того чтобы продолжать копирование на много уровней вглубь):