• //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).
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='PLANETS'>
<HTML>
<xsl:apply-templates/>
</HTML>
</xsl:template>
<xsl:template match='comment()'>
<COMMENT>
<xsl:value-of select='.'/>
</COMMENT>
</xsl:template>
</xsl:stylesheet>
Вот результат для Венеры, в котором комментарий преобразован в элемент <COMMENT>
:
Venus
.815
116.75
3716
.943
66.8<COMMENT>B перигелии</СОММЕNT>
Обратите внимание: здесь текст для других элементов в элементе <PLANET>
также включается в выходной документ, потому что так установлено в соответствии с правилом по умолчанию для каждого элемента. Поскольку для элементов я не предоставил какого-либо правила, их текст просто включается в выходной документ.
Выбор узлов при помощи node()
В образце условие узла node
выбирает любой узел, за исключением корневого узла — помните, что в действительности это child::node()
. Предположим, мы хотим создать таблицу стилей, копирующую произвольный документ XML, используя <xsl:copy>
. (В главе 3 для этого применялся элемент <xsl:copy-of>
.) Можно начать так, как показано в следующем примере. В этом случае в применяемом шаблоне для выбора любого элемента или любого атрибута используется операция OR, с которой мы познакомимся позже в этой главе (этот шаблон фактически выбирает себя — для того чтобы продолжать копирование на много уровней вглубь):
<?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='@*|*'>
<xsl:copy>
<xsl:apply-templates select='@*|*'/>