Выбрать главу
Пример

В этом примере мы будем заменять все элементы элементами вида

<element name="..." position="...">

 ...

</element>

где атрибут name будет содержать имя, a position — через дробь позицию элемента в контексте и размер контекста.

Листинг 6.7. Входящий документ

<а>

 <b/>

 <c/>

 <d>

  <e/>

  <f/>

 </d>

</a>

Листинг 6.8. Преобразование

<xsclass="underline" stylesheet

 version="1.0"

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

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

 <xsclass="underline" strip-space elements="*"/>

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

  <element name="{name()}" pos="{position()}/{last()}">

   <xsclass="underline" apply-templates/>

  </element>

 </xsclass="underline" template>

</xsclass="underline" stylesheet>

Листинг 6.9. Выходящий документ

<element name="a" pos="1/1">

 <element name="b" pos="1/3"/>

 <element name="c" pos="2/3"/>

 <element name="d" pos="3/3">

  <element name="e" pos="1/2"/>

  <element name="f" pos="2/2"/>

 </element>

</element>

Отметим, что если бы мы не удаляли лишние пробельные символы во входящем документе при помощи элемента xsclass="underline" strip-space, в контексте преобразования учитывались бы также и текстовые узлы, которые им соответствуют. Выходящий документ без этого элемента имел бы следующий вид:

<element name="a" pos="1/1">

 <element name="b" pos="2/7"/>

 <element name="c" pos="4/7"/>

 <element name="d" pos="6/7">

  <element name="e" pos="2/5"/>

  <element name="f" pos="4/5"/>

 </element>

</element>

Функция count

number count(node-set)

Функция count возвращает число узлов, которое входит во множество, переданное ей в качестве аргумента.

Пример

Для того чтобы подсчитать количество всех элементов второго уровня, можно воспользоваться выражением count(/*/*). Например, для входящего документа из примера к функциям last и position (листинг 6.7) это выражение примет значение 3.

Приведем несколько других примеров, используя тот же документ.

Покажем, что дерево документа на листинге 6.7 имеет ровно один корневой узел:

count(/) 1

и ровно один элемент, находящийся в корне:

count(/*) 1

Подсчитаем количество текстовых узлов, принадлежащих элементу a (это те самые пробельные текстовые узлы, которые были удалены элементом xsclass="underline" strip-space):

count(/a/text()) 4

Подсчитаем общее количество элементов в документе:

count(//*) 6

Функции local-name, namespace-uri и name

string local-name(node-set?)

string namespace-uri(node-set?)

string name(node-set?)

Функция local-name возвращает локальную часть имени первого в порядке просмотра документа узла множества, переданного ей в качестве аргумента. Эта функция выполняется следующим образом.

□ Если аргумент опущен, то значением функции по умолчанию является множество, содержащее единственный контекстный узел. Иными словами, функция возвратит локальную часть расширенного имени контекстного узла (если она существует).

□ Если аргументом является пустое множество, функция возвращает пустую строку.

□ Если первый в порядке просмотра документа узел переданного множества не имеет расширенного имени, функция возвращает пустую строку.

□ В противном случае функция возвращает локальную часть расширенного имени первого в порядке просмотра документа узла переданного множества.

Функция namespace-uri работает совершенно аналогично функции local-name за тем исключением, что возвращает не локальную часть расширенного имени, a URI пространства имен этого узла. Эта функция выполняется следующим образом.

□ Если аргумент опущен, его значением по умолчанию является множество, содержащее единственный контекстный узел.

□ Если аргументом является пустое множество, функция возвращает пустую строку.

□ Если первый в порядке просмотра документа узел переданного множества не имеет расширенного имени, функция возвращает пустую строку.

□ Если первый в порядке просмотра документа узел переданного множества не принадлежит никакому пространству имен, функция возвращает пустую строку.

□ В противном случае функция возвращает URI пространства имен первого в порядке просмотра документа узла переданного множества.

Функция name возвратит имя вида QName, которое будет соответствовать расширенному имени первого в порядке просмотра документа узла переданного ей множества.

Это имя должно соответствовать расширенному имени узла, то есть должны совпадать локальные части и пространства имен. Вместе с тем, это вовсе не означает, что префиксы также будут совпадать. Например, если в элементе определены несколько префиксов для одного пространства, функция name может использовать любой из них.

Пример

Для следующего элемента

<a:body

 xmlns:a="http://www.a.com"

 xmlns:b="http://www.a.com"

 xmlns:c="http://www.a.com"/>

функция name может вернуть a:body, b:body или c:body.

Большинство процессоров все же возвращает префикс, с которым узел был объявлен.

Так же как local-name и namespace-uri, функция name имеет следующие особенности использования.

□ Если аргумент опущен, то его значением по умолчанию является множество, содержащее единственный контекстный узел.

□ Если аргументом является пустое множество, то функция возвращает пустую строку.

□ Если первый в порядке просмотра документа узел переданного множества не имеет расширенного имени, то функция возвращает пустую строку.

□ В противном случае функция возвращает имя вида QName, соответствующее расширенному имени первого в порядке просмотра документа узла переданного множества.