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

В XSLT доступны следующие функции XPath для работы со строками:

• 

concat(string string1, string string2,...)
. Возвращает конкатенацию (объединение) всех переданных ей строк;

• 

contains(string string1, string string2)
. Возвращает истину, если первая строка содержит (contains) вторую строку;

• 

normalize-space(string string1)
. Возвращает строку
string1
(или контекстный узел, если строки
string1
нет) после отбрасывания лидирующих и завершающих символов-разделителей и замены нескольких последовательных разделителей на один пробел;

• 

starts-with(string string1, string string2)
. Возвращает истину, если первая строка начинается (starts with) со второй подстроки;

• 

string(object)
. Преобразует объект в строку;

• 

string-length(string string1)
. Возвращает количество символов в строке
string1
;

• 

substring(string string1, number offset, number length)
. Возвращает
length
символов из строки, начиная со смещения
offset
;

• 

substring-after(string string1, string string2)
. Возвращает часть строки
string1
после первого вхождения
string2
;

• 

substring-before(string string1, string string2)
. Возвращает часть строки
string1
вплоть до первого вхождения строки
string2
;

• 

translate(string string1, string string2, string string3)
. Возвращает строку
string1
, в которой все вхождения символов в строке
string2
заменены на соответствующие символы в строке
string3
;

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

concat()

Функция

concat
объединяет вместе все переданные ей строки и возвращает полученную строку:

concat(string string1, string string2, ...)

В качестве примера рассмотрите разработанный ранее вариант таблицы стилей

planets.xsl
, отображающей значения элементов и значения атрибутов
UNITS
, в котором шаблоны применяются следующим образом:

Такой код отображает строковое значение, контекстный узел, пробел и строковое значение атрибута UNITS. Но код можно значительно сократить при помощи функции

concat
(листинг 8.8).

Листинг 8.8. Применение функции concat

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

   .

   .

   .





contains()

Функция

contains
проверяет, содержится ли одна строка внутри другой; если это так, функция возвращает истину, если нет — ложь. Функция применяется следующим образом:

boolean contains(container-string, contained-string)

Следующий пример взят из главы 7; в этом случае я хочу осуществить поиск слова «miles» во всех атрибутах, и если оно будет найдено, добавить в результирующий документ текст «You should switch to kilometers.» (Нужно перевести в километры.):

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

   .

   .

   .



 .

 .

 .


You should switch to kilometers.

Вот результирующий документ:

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

   The Planets Table

NameMassRadiusDayDistance
Mercury.0553 (Earth = 1)1516 You should switch to kilometers.58.65 days43.4 You should switch to kilometers.
Venus.815 (Earth = 1)3716 You should switch to kilometers.116.75 days66.8 You should switch to kilometers.
Earth1 (Earth = 1)2107 You should switch to kilometers.1 days128.4 You should switch to kilometers.

normalize-space()

Функция

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

string normalize-space(string?)

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

UNITS
элемента
Меркурия:

Mercury

.0553

58.65

1516

.983

43.4

 .

 .

 .

Функция

normalize-space
поможет удалить лишние пробелы в таблице стилей:

 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

   .

   .

   .

starts-with()

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

starts-with
проверяет, начинается ли одна строка с другой.

boolean starts-with(string-to-examine, possible-start-string)

В этом примере из главы 4 при помощи

starts-with
выбираются текстовые узлы, текст в которых начинается с «Е», для того чтобы выбрать Earth (Землю). Затем в описание Земли добавляется текст «(the World)» (мир), и получается «Earth (the World)»:

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

    .

    .

    .



(the World)



Вот результат — заметьте, что подпись для Земли теперь выглядит как «Earth (the World)»:

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

   .

   .

   .

NameMassRadiusDay
Earth (the World1 (Earth = 1)2107 miles1 days

string()

Функция

string
просто преобразует переданный ей объект в строку. Функция применяется следующим образом:

string string(object?)

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

в
planets.xml
по три элемента
и хотите использовать в качестве фактического названия планеты только первый элемент
:

Mercury

Venus

Earth

.0553

58.65

1516

.983

43.4

Venus

Earth

Mercury

Planet of Love.

.815

116.75

3716

.943

66.8

Earth

Mercury

Venus

The planet you're standing on.

1

1

2107

1

128.4

Предположим теперь, что вам нужно выбрать определенную планету, например, Венеру (Venus). Такая проверка не пройдет, потому что

NAME
вернет набор узлов из всех дочерних элементов
контекстного узла, а так как у каждой планеты есть элемент
со значением «Venus», такое условие всегда будет истиной:

Для того чтобы проверить первый элемент

в каждом элементе
, можно воспользоваться функцией
string
, поскольку она возвращает не набор узлов, а строку:

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

   .

   .

   .



 .

 .

 .

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

контекстного узла, проще воспользоваться
NAME[1]
.

string-length()

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

string-length
возвращает длину (length) переданной ей строки. Функция применяется таким образом:

number string-length(string?)

В следующем примере я определяю длину названия каждой планеты при помощи

string-length
:

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

</code></pre></p><p><pre><code>     Length of Planet Names</code></pre></p><p><pre><code>

     Length of Planet Names


 is

  characters long.



А вот результат:

</code></pre></p><p><pre><code>   Length of Planet Names</code></pre></p><p><pre><code>

   Length of Planet Names

  Mercury is 7 characters long.


  Venus is 5 characters long.


  Earth is 5 characters long.


Этот результирующий документ показан на рис. 8.2.

Рис. 8.2. Определение длины строк в XSLT

substring()

Функция

substring
возвращает подстроку переданной ей строки. Функция применяется следующим образом:

string substring(source-string, start-position, number-of-characters?)

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

source-string
(исходная строка),
start-position
(начальная позиция) и необязательный параметр
number-of-characters
(количество символов). Функция возвращает подстроку исходной строки с начальной позиции и до указанного количества символов или до конца строки, если это количество не задано.

Функция

substring
— одна из трех функций, оперирующих с подстроками:
substring-before
, возвращающая строку перед найденной подстрокой, сама
substring
, возвращающая заданную подстроку, и
substring-after
, возвращающая строку после найденной подстроки. В следующем примере (листинг 8.9) задействованы все три функции: в этом случае я разбил название планеты Меркурий (Mercury) на три подстроки — «Mer», «c» и «ury» — и затем объединил их снова. Вот как это можно сделать при помощи трех рассматриваемых функций (дополнительная информация о
substring-before
и
substring-after
приведена в следующих двух разделах).

Листинг 8.9. Применение функций substring-before, substring и substring-after

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

</code></pre></p><p><pre><code>     Planetary Information</code></pre></p><p><pre><code>

     Planetary Information


   The first planet is

.



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

</code></pre></p><p><pre><code>   Planetary Information</code></pre></p><p><pre><code>

   Planetary Information

  The first planet is Mercury.


substring-after()

Функция

substring-after
возвращает подстроку, которая следует за найденной строкой. В эту функцию передается строка, подстрока, которую нужно найти внутри строки, — и функция возвращает подстроку, расположенную после совпадающей части строки, если она была найдена; иначе функция возвращает пустую строку. Функция применяется следующим образом:

string substring-after(string, string-to-match)

substring-before()

В функцию

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

string substring-before(string, string-to-match)

В разделе

substring()
приведен пример применения функций
substring-before
,
substring
и
substring-after
.

translate()

Функция

translate
служит для перевода или замены определенных символов. (Эта функция во многом похожа на операцию tr в Perl, если вы знакомы с операциями.) В функцию передаются две строки: одна задает список символов поиска, вторая задает список символов, которыми нужно заменить найденные символы. Функция применяется следующим образом:

string translate(string, from-characters, to-characters)

Например, если третий символ из

from-characters
будет найден в
string
, то третий символ из
to-characters
заменит его в результирующей строке. В следующем примере такая функция
translate

translate("steve-starpowder.com", "-", "@")

возвратит результирующую строку «[email protected]».

В этом примере я просто привожу строку к нижнему регистру:

translate("XSLT", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")

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