Преобразование регистра¶
Задача¶
Требуется преобразовать строку, содержащую символы верхнего регистра, в нижний или наоборот.
Решение¶
XSLT 1.0¶
Воспользуйтесь функцией translate()
. Так, следующий код преобразует заглавные буквы в строчные:
1 |
|
А этот код выполняет обратное преобразование:
1 |
|
XSLT 2.0¶
Воспользуйтесь функциями upper-case()
и lower-case()
:
1 2 |
|
Обсуждение¶
Конечно, этот рецепт тривиален. Но я включил его, чтобы воспользоваться случаем и обсудить недостатки решения для XPath 1.0. Преобразование регистров – тривиальная задача лишь до тех пор, пока текст записан в одной локали.
В английском тексте вам вряд ли придется столкнуться со специальными символами, которые содержат диакритические знаки, или такими преобразованиями, когда один символ превращается в два. Самый распространенный пример – немецкий язык, в котором строчная буква Я (β-цет) в верхнем регистре записывается как SS. Во многих современных языках программирования есть функции преобразования регистра, учитывающие локаль, но в XSLT прямой поддержки этой идеи нет. Это печально, поскольку другие средства поддержки интернационализации в XSLT все же включены.
Небольшого улучшения можно добиться, определив для каждого преобразования отдельные XML-компоненты, как в следующем примере:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Эти определения компонентов играют троякую роль. Во-первых, они упрощают перенос таблицы стилей в другую локаль, поскольку изменить нужно лишь определения UPPERCASE
и LOWERCASE
. Во-вторых, они делают код более компактным, так как отпадает необходимость перечислять все буквы алфавита дважды.
В-третьих, наше намерение вызвать функцию translate
становится очевидно всякому человеку, читающему код. Некоторые ревнители чистоты могут возразить против переноса третьего параметра translate
в макрос, но я думаю, что так код читать проще. Если вы тоже сторонник пуризма, то можете писать так: translate($test, &UPPERCASE;, &LOWERCASE;)
.
Я не часто встречал употребление компонентов в книгах, посвященных XSLT, но полагаю, что этот прием обладает рядом достоинств. Вообще, одно из преимуществ записи XSLT-программы в синтаксической нотации XML заключается в том, что вы получаете возможность пользоваться всеми средствами XML, в том числе и определением компонентов. Если вы намереваетесь применять эту технику и планируете написать достаточно много таблиц стилей, то подумайте над тем, чтобы поместить общие определения компонентов во внешний файл и включать их, как показано в примере 2.6. Можно также хранить эти значения в глобальных переменных во внешней таблице стилей и импортировать при необходимости. Такую альтернативу предпочитают многие ветераны XSLT.
Пример 2.6. Файл standard.ent
1 2 3 4 5 |
|
Воспользоваться параметрическим компонентом, определенным в файле standard.ent
, можно, как показано в примере 2.7.
Пример 2.7. Таблица стилей, в которой используется файл standard.ent
1 2 3 4 5 6 7 8 |
|
Реализация преобразования регистра, предложенная Стивом Болом (Steve Ball) и работающая практически во всех случаях, достигает этого за счет включения большинства общеупотребительных символов Unicode в строки, записанные в верхнем и нижнем регистре. При этом немецкая буква β обрабатывается специально.
XSLT 2.0¶
Добавленные в XPath 2.0 функции upper-case()
и lower-case()
решают большую часть проблем, связанных с преобразованием регистра в не-английских алфавитах.
Единственное исключение касается преобразований с учетом местных особенностей. Лучше не пользоваться этими функциями для сравнения строк без учета регистра. Вместо этого обратитесь к функции compare()
, указав таблицу сравнения (collation), в которой регистр игнорируется. Пользователь Saxon 8.x найдет информацию о таблицах сравнения на страницах http://www.saxonica.com/documentation/conformance/collation-uri.html и http://www.saxonica.com/documentation/extensions/instructions/collation.html.