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

Функции XPath для работы с наборами узлов

Следующие функции XPath работают с наборами узлов:

• count(node-set). Возвращает число узлов в наборе узлов;

• id(string ID). Возвращает набор узлов элемента, ID которого совпадает с переданной функции строкой, или пустой набор узлов, если таковых элементов не оказалось;

• last(). Возвращает число узлов в наборе узлов;

• local-name(node-set). Возвращает локальное имя первого узла в наборе узлов;

• name(node-set). Возвращает полное имя первого узла в наборе узлов;

• namespace-uri(node-set). Возвращает URI пространства имен первого узла в наборе узлов;

• position(). Возвращает позицию контекстного узла в контекстном наборе узлов, начиная с 1.

count()

Функция count подсчитывает число узлов в наборе узлов

number count(node-set)

Функция принимает набор узлов и возвращает количество узлов в этом наборе. Следующий пример применения функции count мы уже рассматривали в главе 6. В этом случае набор узлов образован из всех элементов <PLANET> в planets.xml; я получил его при помощи пути расположения «//PLANET»:

<xsclass="underline" stylesheet

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

 <xsclass="underline" output method="xml" indent="yes"/>

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

  <xsclass="underline" copy>

   <xsclass="underline" apply-templates/>

  </xsclass="underline" copy>

 </xsclass="underline" template>

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

  <xsclass="underline" copy use-attribute-sets="numbering">

   <xsclass="underline" apply-templates/>

  </xsclass="underline" copy>

 </xsclass="underline" template>

 <xsclass="underline" attribute-set name="numbering">

  <xsclass="underline" attribute name="number"><xsclass="underline" number/></xsclass="underline" attribute>

  <xsclass="underline" attribute name="total">

   <xsclass="underline" value-of select="count(//PLANET)"/>

  </xsclass="underline" attribute>

 </xsclass="underline" attribute-set>

</xsclass="underline" stylesheet>

Заметьте, что в приведенном ниже результате каждый элемент <PLANET> обладает и атрибутом number, и атрибутом total, а атрибут total хранит общее количество элементов <PLANET>, которое было найдено при помощи count:

<?xml version="1.0" encoding="UTF-8"?>

<PLANETS>

 <PLANET number="1" total="3">

  <NAME>Mercury</NAME>

  <MASS>.0553</MASS>

  <DAY>58.65</DAY>

  <RADIUS>1516</RADIUS>

  <DENSITY>.983</DENSITY>

  <DISTANCE>43.4</DISTANCE>

 </PLANET>

 <PLANET number="2" total="3">

  <NAME>Venus</NAME>

  <MASS>.815</MASS>

  <DAY>116.75</DAY>

  <RADIUS>3716</RADIUS>

  <DENSITY>.943</DENSITY>

  <DISTANCE>66.8</DISTANCE>

 </PLANET>

 <PLANET number="3" total="3">

  <NAME>Earth</NAME>

  <MASS>1</MASS>

  <DAY>1</DAY>

  <RADIUS>2107</RADIUS>

  <DENSITY>1</DENSITY>

  <DISTANCE>128.4</DISTANCE>

 </PLANET>

</PLANETS>

id()

Функция id возвращает набор узлов, в котором все узлы имеют такой же ID, как и переданный в эту функцию. Функция применяется следующим образом:

node-set id(id-value)

В функцию передается значение ID, и она возвращает набор узлов с узлами, имеющими этот ID. Заметьте, что вы можете задать несколько ID, разделенных символами-разделителями, и функция вернет набор узлов с элементами, обладающими этими ID.

Следующее правило-пример выбирает текст всех элементов с ID «favorite»:

<xsclass="underline" template match = "id('favorite')">

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

</xsclass="underline" template>

Отметьте также, что вы должны объявлять значения ID как в DTD или схеме. Объявление DTD для planets.xml, объявляющее ID с именем id и присваивающее ему значение «favorite», может выглядеть так:

<?xml version="1.0"?>

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

<!DOCTYPE PLANETS [

<!ELEMENT PLANET (CUSTOMER)*>

<!ELEMENT CUSTOMER (NAME,MASS,RADIUS,DAY)>

<!ELEMENT NAME (#PCDATA)>

<!ELEMENT MASS (#PCDATA)>

<!ELEMENT RADIUS (#PCDATA)>

<!ELEMENT DAY (#PCDATA)>

<!ATTLIST PLANET

 id ID #REQUIRED>

]>

<PLANETS>

 <PLANET id='favorite'>

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

 .

 .

 .

Заметьте, что некоторые процессоры XSLT не могут осуществлять выборку по ID, потому что они не читают объявления DTD и схему XML. Это одна из задач, которые призван решить XSLT 2.0 — сделать доступной информацию об идентификаторах.

last() 

Функция last возвращает число узлов в наборе узлов, поэтому ее значение равно позиции последнего узла. Она применяется следующим образом:

number last()

Следующий пример из главы 5 последовательно выводит в результирующий документ имена планет. Однако я хочу, чтобы выводилось не просто «The first three planets are: Mercury Venus Earth» (первые три планеты: Меркурий Венера Земля), a «The first three planets are: Mercury, Venus, and Earth.» Необходимые знаки пунктуации можно добавить, определяя элемент, с которым мы работаем, при помощи функции position и проверяя позицию при помощи <xsclass="underline" if>: