XSLT — страница 68 из 124

;

generate-id()
;

system-property()
;

unparsed-entity-uri()
.

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

count()
;

id()
;

last()
;

local-name()
;

name()
;

namespace-uri()
;

position()
.

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

concat()
;

contains()
;

normalize-space()
;

starts-with()
;

string()
;

string-length()
;

substring()
;

substring-after()
;

substring-before()
;

translate()
.

Для работы с числами служат следующие функции XPath:

ceiling()
;

floor()
;

number()
;

round()
;

sum()
.

И эти функции XPath работают с логическими значениями:

boolean()
;

false()
;

lang()
;

not()
;

true()
.

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

Функции XSLT

В следующем списке перечислены встроенные в XSLT функции:

• 

current()
. Возвращает текущий (current) узел — но не контекстный узел. Текущий узел — это узел, используемый в данный момент в таких циклах, как
. Функцию current нельзя применять в образцах;

• 

document()
. Позволяет считывать несколько документов;

• 

element-available()
. Показывает, доступен ли элемент расширения;

• 

format-number()
. Форматирует числа при выводе;

• 

function-available()
. Показывает, доступна ли функция расширения;

• 

generate-id()
. Указывает процессору XSLT присвоить идентификатор узлу и возвратить его. При повторном применении generate-id к тому же узлу функция возвращает присвоенный ранее идентификатор;

• 

key()
. Позволяет осуществлять поиск по ключу;

• 

system-property()
. Позволяет проверить три системных свойства:
xsl:version
(версия XSLT, поддерживаемая процессором XSLT),
xsl:vendor
(производитель процессора XSLT) и
xsl:vendor-url
(URL производителя процессора XSLT);

• 

unparsed-entity-uri()
. Предоставляет доступ к неразобранным сущностям, объявленным в DTD или схеме, через URI.

В следующих разделах все эти функции рассматриваются подробно и с примерами.

current()

Функция

current
возвращает текущий (current) — не контекстный (context) — узел. Контекстный узел шаблона — это узел в выбранном наборе узлов, к которому применяется шаблон. Текущий узел, с другой стороны, это используемый в данный момент узел в таких циклах, как
. Функция возвращает текущий узел как набор узлов с одним узлом:

node-set current()

Обратите внимание:

current
нельзя применять в образцах, поскольку образцы должны быть независимы от пути обработки, а способы реализации таких структур, как циклы, в процессорах XSLT могут различаться.

Следующий пример, в котором я выбираю элементы

при помощи шаблона (листинг 8.1), демонстрирует работу функции
current
. Внутрь шаблона я поместил элемент
, и шаблон применяется только в том случае, если выбранный шаблоном контекстный узел в то же время является и текущим узлом в очередной итерации в элементе
.

Листинг 8.1. Применение функции current

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

   .

   .

   .

NameMassRadiusDay




Результат применения этой таблицы стилей будет точно таким же, как если бы элемента

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

document()

Функция

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

node-set document(uri, base-uri?)

Функция принимает параметр

uri
, который может представлять собой URI читаемого документа или набор узлов, чьи строковые значения задают идентификаторы URI. Второй, необязательный параметр
base-uri
представляет собой набор узлов, базовый URI которого используется для вычисления всех относительных URI, могущих находиться в параметре
uri
.

В следующем примере (листинг 8.2) я обрабатываю в процессоре XSLT один документ,

planets1.xml
, и также считываю и обрабатываю второй документ,
planets2.xml
. Вот
planets1.xml
.

Листинг 8.2. planets1.xml

Вот

planets2.xml
— в элементе
содержится одна планета (листинг 8.3).

Листинг 8.3. planets2.xml

Mercury

.0553

58.65

1516

.983

43.4

А вот таблица стилей

planets.xml
, которую я применяю к
planets1.xml
. Таблица стилей содержит шаблон, выбирающий элемент
в
planets1.xml
, и в этом шаблоне я считываю
planets2.xml
при помощи
и функции
document
(листинг 8.4).

Листинг 8.4. Применение функции document

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

</code></pre></p><p><pre><code>     The Planets Table</code></pre></p><p><pre><code>

     The Planets Table

NameMassRadiusDay


 .

 .

 .

Эта таблица стилей обрабатывает данные в

planets1.xml
и также считывает и обрабатывает
planets2.xml
; вот полный результат — как видите, данные для
planets2.xml
добавились нужным образом:

</code></pre></p><p><pre><code>   The Planets Table</code></pre></p><p><pre><code>

   The Planets Table

NameMassRadiusDay
Mercury.0553 (Earth = 1)1516 miles58.65 days

Функция

document
удобна, поскольку позволяет считывать на этапе выполнения такие дополнительные документы, как справка о правах владения или отказе от них, фирменный бланк и т.п.

element-available()

Функция

element-available()
используются для определения доступности определенного элемента расширения. Ее применяют следующим образом:

boolean element-available(element-name)

Функция принимает имя искомого элемента и, если элемент доступен, возвращает истину, если недоступен — ложь.

Мы уже встречались с этой функцией в главе 5. В примере

element-available
той главы я проверял наличие элемента
таким образом:

Sorry, can't do math today.

format-number()

Как можно догадаться по имени, функция

format-number()
служит для форматирования чисел с преобразованием их в строки. Она применяется так:

string format-number(number, format, name?)

Функция возвращает форматируемое число в виде строки. Функции передаются число

number
, которое нужно отформатировать, строка форматирования
format
и необязательный параметр-строка
name
. Строка name — это имя
QName
, задающее формат так, как он создается элементом
(который будет рассмотрен в конце этой главы).

Форматирующая строка

format
должна соответствовать соглашениям класса Java
DecimalFormat
.

КЛАСС JAVA DECIMALFORMAT

На момент написания книги документация для класса Java DecimalFormat находится в Интернете по адресу: http://java.sun.com/products/jdk/1.1/docs/api/java.text.DecimalFormat.html.

Форматирующая строка (format string) состоит из следующих частей:

• 

format-string:= subpattern (;subpattern)?

• 

subpattern:= prefix? integer (.fraction)?suffix?

• 

prefix:= [#x0..#xFFFD] - specialCharacters

• 

suffix:= [#x0..#xFFFD] - specialCharacters

• 

integer:= '#'* '0'* '0'

• 

fraction:= '0'* '#'*

Далее показаны специальные символы (

specialCharacters
), которые можно использовать в подчиненных образцах,
subpattern
(эти символы можно изменить при помощи элемента
, который будет рассмотрен в конце этой главы):

• 

0
— на этом месте всегда должна стоять цифра;

• 

#
— цифра, если только это не избыточный лидирующий или завершающий ноль;

• 

.
— разделитель десятичной части;

• 

,
— разделитель групп разрядов;

• 

;
— разделяет форматы;

• 

-
— знак минуса;

• 

%
— умножить на 100 и показать как проценты;

• 

— умножить на 1000 и показать в тысячных частях;

• 

Е
— разделяет мантиссу и экспоненциальную часть;

• 

¤
— символ валюты (#xA4);

• 

'
— заключает в кавычки специальные символы.

Следующий пример (листинг 8.5) демонстрирует работу функции. Я форматирую значения из

planets.xml
, отображаемые в таблице HTML.

Листинг 8.5. Форматирование чисел

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

  .

  .

  .





Вот результат, в котором выведены отформатированные числа:

</code></pre></p><p><pre><code>   The Formatted Planets Table</code></pre></p><p><pre><code>

   The Formatted Planets Table

NameMassRadiusDay
Mercury0.055 (Earth = 1)1.516 miles58.65 days
Venus0.815 (Earth = 1)3.716 miles116.75 days
Earth1 (Earth = 1)2.107 miles1 days

Этот результирующий документ показан на рис. 8.1. (MSXML3 и Saxon отбрасывают лидирующие нули, поэтому 0.055 выводится как .055 и т.д.)

Рис. 8.1. Форматирование чисел при помощи XSLT 


Следующие примеры демонстрируют способы применения форматирующих строк. Заметьте, что при помощи точки с запятой (;) можно отделять образцы для положительных и отрицательных чисел.

ЧислоФорматирующая строкаРезультат
4567#,###4,567
4567.8####.#4567.8
4567.8#,##0.004,567.80
456.789#,##0.00456.79
4567890#,##0.004,567,890.00
4567###0.0###4567.0
.00045##0.0###0.0005
.45#00%45%
-4.56#.00;(#.00)(4.56)
-45#,##0.00-45

function-available()

При помощи функции XSLT 1.0

function-available
можно проверить наличие функции расширения:

boolean function-available(function-name)

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

Следующий пример мы уже рассматривали в главе 5. В этом случае я хочу выполнить ряд математических операций при помощи функции расширения

starpowder:calculate
, и если она отсутствует, вывести в результирующий документ текст «Sorry, can't do math today.» (Извините, сегодня математические вычисления не работают.). Можно, конечно, также прекратить обработку и вывести сообщение об ошибке при помощи элемента
:

Sorry, can't do math today.

generate-id()

Функция

generate-id
дает указание процессору XSLT присвоить узлу идентификатор (который возвращается как строка). Функция применяется следующим образом:

string generate-id(node)

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

Следующий пример взят из главы 6, но сейчас я собираюсь добавить в

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

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

</code></pre></p><p><pre><code>     The Planets Table</code></pre></p><p><pre><code>

     The Planets Table

    .

    .

    .

Этот код добавляет каждой планете идентификатор и создает нужные гиперссылки. Я могу создать закладки гиперссылки в HTML-таблице данных планет, установив по очереди атрибут

закладки в идентификатор для каждого элемента
так, чтобы он стал гиперссылкой-назначением:

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

   .

   .

   .



 .

 .

 .

Вот и все; сейчас я создал гиперссылки с атрибутом

HREF
, значение которого равно идентификатору элемента
; при помощи же этого идентификатора я сделал каждый элемент
назначением гиперссылки.

Когда пользователь щелкает на гиперссылку в оглавлении, браузер прокручивает данные до соответствующей записи планеты в HTML-таблице. Вот как выглядит результирующий документ при использовании процессора Xalan: 

</code></pre></p><p><pre><code>   The Planets Table</code></pre></p><p><pre><code>

   The Planets Table

Mercury

Venus

Earth

NameMassRadiusDay
Mercury.0553 (Earth = 1)1516 miles58.65 days
Venus.815 (Earth = 1)3716 miles116.75 days
Earth1 (Earth = 1)2107 miles1 days

key()

Функция

key
служит для поиска узлов с определенным значением по именованному ключу, ее следует применять следующим образом:

node-set key(name, value)

Функции передаются имя ключа

name
в виде строки и требуемое значение ключа
value
, которое нужно найти. Функция возвращает набор узлов из найденных узлов.

Ключи создаются при помощи элемента

. Мы уже видели следующий пример в главе 4 — здесь я при помощи ключей выбираю планеты, чей атрибут
COLOR
установлен в «
BLUE
»:

 .

 .

 .

Earth

"(Earth = 1)">1

1

2107

1

128.4

Теперь при помощи

я могу создать ключ
COLOR
, выбирающий элементы
и проверяющий их атрибут
COLOR
. Вот как он выглядит:

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

 .

 .

 .

Теперь я могу применить образец «

key()
» для выбора элементов
с атрибутом
COLOR
со значением «
BLUE
» таким образом:

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

   .

   .

   .

NameMassRadiusDay

 .

 .

 .

И вот результат — как видите, единственной планетой, удовлетворившей образцу, была Земля:

<НЕАD>

</code></pre></p><p><pre><code>   The Planets Table</code></pre></p><p><pre><code>

   The Planets Table

NameMassRadiusDay
Earth1 (Earth = 1)2107 miles1 days

system-property()

Функция

system-property
возвращает значение нескольких системных свойств в виде строк; вот как ей следует пользоваться:

string system-property(property)

Можно проверять следующие возможные значения системного свойства

property
:

xsl:version
. Возвращает версию XSLT;

xsl:vendor
. Возвращает строку, идентифицирующую производителя процессора XSLT;

xsl:vendor-url
. Возвращает URL производителя процессора XSLT.

Вот пример — версию XSLT можно проверить, вызвав

system-property('xsl:version')
;

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

 .

 .

 .

 .

 .

 .

Проверка версии XSLT может понадобиться, если вы хотите воспользоваться возможностями, которые появились в последних версиях.

unparsed-entity-uri()

Функция

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

string unparsed-entity-uri(name)

В функцию передается имя name неразобранной сущности, и функция возвращает для нее идентификатор. В следующем примере (листинг 8.6) я добавил в

planets.xml
DTD и объявил три неразобранных сущности, соответствующих рисункам планет —
image1
,
image2
и
image3
, — и обратился к ним, добавив в каждый элемент
атрибут
IMAGE
.

Листинг 8.6. planets.xml с неразобранными сущностями

]>

Mercury

.0553

58.65

1516

.983

43.4

Venus

.815

116.75

3716

.943

66.8

Earth

1

1

2107

1

128.4