Технология XSLT — страница 40 из 66

Функция current

Выражение для этой функции имеет вид:

node-set current()

Функция

current
возвращает множество, состоящее из текущего узла преобразования.

Мы часто использовали термины текущий узел и узел контекста как синонимы: действительно, в большинстве случаев между ними нет никакой разницы, текущий узел преобразования совпадает с узлом контекста вычисления выражений. Однако бывают ситуации, когда они являются двумя различными узлами.

Представим себе, что нам нужно выбрать элементы

item
со значением атрибута
source
, равным значению этого атрибута текущего узла. Очевидно, путь выборки будет выглядеть как
item[предикат]
, где предикат определяет условие равенства атрибутов текущего и выбираемого. Но как записать это условие? Предикат будет вычисляться в контексте проверяемого элемента
item
, значит, все относительные пути выборки типа
@source
или
./@source
или
self::item/@source
будут отсчитываться именно от проверяемого элемента. В этом случае узел контекста и текущий узел преобразования — не одно и то же.

Для того чтобы обратиться в предикате именно к текущему узлу, следует использовать функцию

current
:

item[@source=current()/@source]

Это выражение выберет все дочерние элементы

item
текущего узла, значение атрибута
source
которых будет таким же, как и у него.

Функция unparsed-entity-uri

Выражение для этой функции следующее:

string unparsed-entity-uri(string)

Функция

unparsed-entity-uri
возвращает уникальный идентификатор ресурса, который соответствует неразбираемой внешней сущности, имя которой передано как аргумент.

Пример

Описывая синтаксис XML, мы приводили пример документа, который использовал неразбираемые внешние сущности.

Листинг 8.67. Входящий документ использующий неразбираемые внешние сущности

  image ENTITY #REQUIRED

  title CDATA #REQUIRED

  href CDATA #REQUIRED>

]>

Для того чтобы вычислить местоположение графических файлов, соответствующих пунктам этого меню, нужно будет использовать функцию

unparsed- entity-uri
. Аргументом этой функции в данном случае будет значение атрибута
image
, ведь именно этот атрибут задает имя неразбираемой сущности, которая соответствует изображению пункта меню. Преобразование такого документа в HTML будет иметь приблизительно следующий вид.

Листинг 8.68. Преобразование, использующее функцию unparsed-entity-uri

 version="1.0"

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


  method="html"

  indent="yes"/>




Результат преобразования приведен на следующем листинге.

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

Остается только добавить, что

unparsed-entity-uri
— это единственная функция, которая позволяет работать с неразбираемыми сущностями. Никаких средств для обработки нотаций и вспомогательных приложений, которые им соответствуют, в XSLT нет. Сказывается тот факт, что неразбираемые сущности и нотации очень редко используются в документах, поэтому их поддержка в XSLT минимальна.

Функция generate-id

Синтаксическая конструкция этой функции:

string generate-id(node-set?)

Функция

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

Функция

generate-id
обладает следующими свойствами.

□ Функция

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

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

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

□ Процессор не обязан генерировать один и тот же идентификатор при разных выполнениях преобразования одного и того же документа. Иными словами, если в понедельник процессор

X
при выполнении преобразования
Y
сгенерирует для узла
Z
документа
D
идентификатор
I
, то во вторник тот же процессор
X
при выполнении того же преобразования
Y
с тем же документом
D
может сгенерировать для того же самого узла
Z
совершенно другой, отличный от
I
идентификатор.

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

generate-id
.

□ Генерируемый идентификатор может совпадать, а может и не совпадать со значениями уникальных атрибутов, то есть атрибутов, тип данных которых объявлен в блоке DTD как

ID
.

Помимо очевидного применения, например, для явного задания уникального идентификатора в выходящем документе, функция

generate-id
совершено неожиданным образом облегчает задачи группировки. Подробнее об этом мы расскажем в главе 11.

Пример

Предположим, что в наших XML-документах изменилась логическая схема: теперь каждый элемент

item
должен обладать уникальным атрибутом
id
.

Выполнить задачу конвертации может простое преобразование.

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

 version="1.0"

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




В выходящем документе элементы

item
будут иметь уникальные идентификаторы.

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

 ...

Сразу оговоримся, что этот способ будет работать не всегда:

generate-id
создает идентификатор, который является уникальным среди всех остальных идентификаторов узлов, а не среди всех значений уникальных атрибутов документа. Так что если бы какой-либо элемент имел ID-атрибут со значением
b1b1b4
, выходящий документ перестал бы быть правильным. Однако же, если в документе до преобразования вообще не было уникальных атрибутов, все будет в порядке.

Функция system-property

Синтаксис этой функции приведен ниже:

object system-property(string)

Функция

system-property
возвращает значение свойства, которое определяется ее строковым параметром. Аргумент этой функции должен представлять расширенное имя системного свойства. Если процессор не поддерживает свойство с таким именем, функция должна вернуть пустую строку.

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

xsl:version
— это свойство должно возвращать номер версии языка XSLT, которую поддерживает данный процессор.

xsl:vendor
— это свойство должно возвращать текстовую информацию о производителе используемого процессора.

xsl:vendor-uri
— это свойство должно возвращать URL производителя — как правило,
xsl:vendor-uri
— это адрес Web-сайта производителя процессора.

К сожалению, в первой версии языка XSLT процессоры обязаны поддерживать только эти свойства. Очень полезным, было бы, например, свойство, возвращающее имя преобразования или преобразовываемого файла. К сожалению, ничего подобного в стандарте не предусмотрено.

Пример

В качестве примера приведем небольшой шаблон, выводящий в виде комментария информацию о процессоре.

Листинг 8.72. Шаблон, выводящий системную информацию


 | XSLT Version: 

   select="format-number(system-property('xsl:version'), '0.0')"/>


 | XSLT Processor: 


 | URL: 


 +

Процессор SAXON, написанный Майклом Кеем (Michael Kay), выводит следующий комментарий:

Ожидается, что в будущих версиях XSLT набор системных свойств будет расширен. Кроме того, многие процессоры поддерживают дополнительные системные свойства, не оговоренные в спецификации.

Глава 9