Алексей Валиков - Технология XSLT
<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 (это те самые пробельные текстовые узлы, которые были удалены элементом xsl: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, соответствующее расширенному имени первого в порядке просмотра документа узла переданного множества.
ПримерМы можем видоизменить преобразование, приведенное в примере к функциям last и position (листинг 6.7), чтобы генерируемые элементы содержали информацию об имени, пространстве имен и локальной части имени элементов.
Листинг 6.10. Входящий документ<a:a
xmlns:a="http://www.a.com"
xmlns:b="http://www.b.com">
<b:b>
<c/>
</b:b>
</a:a>
Листинг 6.11. Преобразование<xsl:stylesheet
version="1.0"
xmlns:xsl="http: //www.w3.org/1999/XSL/Transform"
xmlns:a="http://www.a.com"
xmlns:b="http://www.b.com">
<xsl:output indent="yes"/>
<xsl:template match="*">
<element
name="{name()}"
namespace-uri="{namespace-uri()}"
local-name="{local-name()}">
<xsl:apply-templates/>
</element>
</xsl:template>
</xsl:stylesheet>
Листинг 6.12. Выходящий документ<element
xmlns:a="http://www.a.com"
xmlns:b="http://www.b.com"
name="a:a"
namespace-uri="http://www.a.com"
local-name="a">
<element name="b:b"
namespace-uri="http://www.b.com"
local-name="b">
<element name="c"
namespace-uri=""
local-name="c"/>
</element>
</element>
Функция id
node-set id(object)
Мы уже встречались с функцией id, когда говорили об уникальных атрибутах элементов и еще раз — когда разбирали паттерны. Функция id позволяет обращаться к элементам по значениями их уникальных атрибутов.
Функция id выполняется по-разному в зависимости от того, какой тип данных ей передается.
□ Если аргументом функции является строка, она рассматривается как набор идентификаторов, разделенных пробелами. В результирующее множество узлов войдут узлы тех элементов текущего документа, значения уникальных атрибутов которых входят в набор идентификаторов, определяемый строковым аргументом.
□ Если аргументом функции является множество узлов, результатом ее выполнения будет объединение результатов функции id, примененной к строковому значению каждого из узлов множества.
□ Если аргументом функции является объект другого типа, аргумент вначале преобразуется в строку и функция id выполняется как со строковым параметром.
ПримерПредположим, что мы используем XML для того, чтобы описать граф — множество вершин, соединенных дугами (рис. 6.11).
Рис. 6.11. Изображение графа, который мы будем описывать в XML
Каждой вершине будет соответствовать элемент vertex. Для того чтобы описать все связи, мы дадим каждой вершине уникальное имя, которое будет записано в ее ID-атрибуте name. Имена вершин, с которыми она соединена, будут перечислены в атрибуте connects типа IDREFS.
Документ, описывающий этот граф, может выглядеть следующим образом.
Листинг 6.13. Документ gemini.xsl<!DOCTYPE vertices SYSTEM "gemini.dtd">
<vertices>
<vertex name="alpha" connects="tau"/>
<vertex name="beta" connects="upsilon"/>
<vertex name="gamma" connects="zeta"/>
<vertex name="delta" connects="zeta lambda upsilon"/>
<vertex name="epsilon" connects="nu mu tau"/>
<vertex name="zeta" connects="delta gamma"/>
<vertex name="theta" connects="tau"/>
<vertex name="iota" connects="tau upsilon"/>
<vertex name="kappa" connects="upsilon"/>
<vertex name="lambda" connects="delta xi"/>
<vertex name="mu" connects="epsilon"/>
<vertex name="nu" connects="epsilon"/>
<vertex name="xi" connects="lambda"/>
<vertex name="tau" connects="alpha theta iota epsilon"/>
<vertex name="upsilon" connects="beta iota kappa delta"/>
</vertices>
Декларация типа документа вынесена во внешний файл gemini.dtd.