<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
:
<xsl:template match='PLANET[@COLOR]'>
.
.
.
</xsl:template>
А что, если нам требуется выбрать планеты, у которых атрибут COLOR
имеет значение 'BLUE
' (голубой)? Это можно сделать при помощи операции =, как показано в листинге 4.5.
<'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='PLANET[@COLOR = 'BLUE']'>
The <xsl:value-of select='NAME'/> is blue.
</xsl:template>
<xsl:template match='text()'>
</xsl:template>
</xsl:stylesheet>
Таблица стилей из листинга 4.5 отбирает планеты с голубым цветом и убирает остальные, выключая правило по умолчанию для текстовых узлов. Результат следующий:
<HTML>
The Earth is blue.
</HTML>
Создание предикатов
Предикаты — настоящие выражения XPath, и XPath гораздо ближе к настоящему языку, чем образцы: к примеру, выражения XPath могут возвращать не только списки узлов, но также логические, строковые и числовые значения. Выражения XPath могут работать не только с текущим узлом или дочерними узлами: можно работать с родительскими узлами, узлами-предками и другими узлами.
Глава 7 полностью посвящена XPath, но имеет смысл предоставить введение в предмет здесь, при обсуждении образцов, потому что часть предиката образца обладает наибольшими возможностями. В предикатах могут быть все виды выражений; в следующем списке перечислен ряд возможных типов, которые будут изучены в следующих разделах:
• наборы узлов;
• логические выражения;
• числа;
• строки.
Предикаты: наборы узлов
Набор узлов (node set), как понятно из названия, представляет собой просто совокупность узлов (и может содержать только один узел). Выражение child::PLANET
возвращает набор узлов, состоящий из всех элементов <PLANET>
. Выражение child::PLANET/child::NAME
возвращает список узлов, состоящий из всех элементов <NAME>
, дочерних по отношению к элементам <PLANET>
. Для выбора узла или узлов из набора узлов воспользуйтесь следующими функциями для работы с наборами узлов в предикатах:
• last()
. Возвращает количество узлов в наборе узлов;
• position()
. Возвращает позицию контекстного узла в контекстном наборе узлов (начиная с 1);
• count(node-set)
. Возвращает количество узлов в наборе. Если опустить node-set
, функция будет применена к контекстному узлу;
• id(string ID)
. Возвращает набор узлов, содержащий элемент с ID, удовлетворяющим переданной функции строке, или пустой набор узлов, если такой элемент отсутствует. Можно перечислить несколько идентификаторов, разделенных символами-разделителями, — тогда функция вернет набор узлов, состоящий из элементов с этими идентификаторами;
• local-name(node-set)
. Возвращает локальное имя первого узла в наборе узлов. Если опустить node-set
, функция будет применена к контекстному узлу;
• namespace-uri(node-set)
. Возвращает URI пространства имен первого узла в наборе узлов. Если опустить node-set
, функция будет применена к контекстному узлу;
• name(node-set)
. Возвращает полностью определенное имя первого узла в наборе узлов. Если опустить node-set
, функция будет применена к контекстному узлу.
В листинге 4.6 я перенумеровал элементы в выходном документе при помощи функции position()
.
<?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>
The Planets
</TITLE>