Алексей Валиков - Технология XSLT
- Название:Технология XSLT
- Автор:
- Жанр:
- Издательство:БХВ-Петербург
- Год:2002
- Город:Санкт-Петербург
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алексей Валиков - Технология XSLT краткое содержание
Книга посвящена разработке приложений для преобразования XML-документов с использованием XSLT — расширяемого языка стилей для преобразований. Обсуждается применение языков XSLT и XPath в решении практических задач: выводу документов в формате HTML, использованию различных кодировок для интернационализации и, в частности, русификации приложений, вопросам эффективности существующих подходов для решения проблем преобразования. Для иллюстрации материала используется большое количество примеров.
Для начинающих и профессиональных программистов
Технология XSLT - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
/items/item[@source='a']
Тогда для каждого элемента item
в его группу войдут элементы, которые будут выбраны выражением
/items/item[@source=current()/@source]
Попробуем использовать этот факт в следующем шаблоне:
Как и ожидалось, при применении этого правила к элементам item
для каждого из них будет создана группа, принадлежащая тому же источнику, — уже хороший результат, но в условии требуется создать по группе не для каждого объекта, а для каждого источника. Чтобы достичь этого, можно создавать группу только для первого объекта, принадлежащего ей. Провести такую проверку опять же несложно: объект будет первым в группе тогда и только тогда, когда ему не предшествуют другие, элементы item
, принадлежащие тому же источнику. Иначе говоря, создаем группы только для тех элементов, для которых выражение
preceding-sibling::item[@source-current()/@source]
будет возвращать пустое множество.
С небольшими добавлениями искомое преобразование целиком будет иметь вид.
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
test="preceding-sibling::item[@source=current()/@source]"/>
Бесспорно, решение было несложным, но довольно громоздким. Самым же узким местом в этом преобразовании является обращение к элементам item
источника текущего элемента посредством сравнения атрибутов source
.
Проблема совершенно стандартна для многих преобразований: нужно выбирать узлы по определенным признакам, причем делать это нужно как можно более эффективно. Хорошо, что в нашем документе было всего восемь элементов item
, но представьте себе ситуацию, когда элементов действительно много.
Проблема, которую мы подняли, достаточно серьезна. Она состоит в оптимизации поиска узлов с определенными свойствами в древовидно организованной структуре.
Попробуем разобраться в смысле фразы "узел обладает определенными свойствами". Очевидно, это означает, что для этого узла выполняется некое логическое условие, иначе говоря, некий предикат обращается в "истину".
Однако какого именно типа условия мы чаще всего проверяем? Анализируя различные классы задач, можно придти к выводу, что в большинстве случаев предикаты являются равенствами — выражениями, которые обращаются в "истину" тогда и только тогда, когда некоторый параметр узла, не зависящий от текущего контекста, равен определенному значению. В нашем примере смысл предиката на самом деле состоит не в том, чтобы проверить на истинность выражение @source=current()/@source
, а в том, чтобы проверить на равенство @source
и current()/@source
.
Если переформулировать это для общего случая, то нам нужно выбрать не те узлы, для которых истинно выражение A=B
, скорее нужно выбрать те, для которых значение A
равно значению B
. Иначе говоря, узел будет идентифицироваться значением в своего свойства A
. И если мы заранее вычислим значения свойств A
, проблема поиска узлов в дереве сведется к классической проблеме поиска элементов множества (в нашем случае — узлов дерева) по определенным значениям ключей (в нашем случае — значениями свойств A
).
Чтобы пояснить это, вернемся к нашему примеру: мы ищем элементы item
со значением атрибута source
, равным заданному. Свойством, идентифицирующим эти элементы, в данном случае будут значения их атрибутов source
, которые мы можем заранее вычислить и включить в табл. 8.2.
Таблица 8.2. Значения атрибута source
элементов item
Идентификатор (значение атрибута source ) |
Элемент item |
---|---|
a |
|
a |
|
a |
|
b |
|
b |
|
b |
|
с |
|
с |
Таким образом, значение "с"
идентифицирует объекты с именами D
и G
, а значение "а"
— объекты с именами A
, C
и H
, причем находить соответствующие элементы в таблице по их ключевому свойству не составляет никакого труда.
Несмотря на то, что произведенные нами манипуляции чрезвычайно просты (и настолько же эффективны), процессор вряд ли в общем случае сможет сделать что-либо подобное сам, и потому очень важной является возможность явным образом выделять в XSLT-преобразованиях ключевые свойства множеств узлов.
В этом разделе мы будем рассматривать две конструкции, позволяющие манипулировать множествами узлов посредством ключей — это элемент xsl:key
, который определяет в преобразовании именованный ключ, и функция key
, которая возвращает множество узлов, идентифицирующихся заданными значениями ключей.
Элемент xsl:key
Синтаксис элемента несложен:
name=" имя "
match=" паттерн "
use=" выражение "/>
Элемент верхнего уровня xsl:key
определяет в преобразовании ключ именем, заданным в значении атрибута name
, значением которого для каждого узла документа, соответствующего паттерну match
, будет результат вычисления выражения, заданного в атрибуте use
. Ни атрибут use
, ни атрибут match
не могут содержать переменных.
В нашем примере элементы item
идентифицируются значениями своих атрибутов source
. Для их идентификации мы можем определить ключ с именем src
следующим образом:
Следуя строгому определению, данному в спецификации языка, ключом называется тройка вида ( node , name , value )
, где node
— узел, name
— имя и value
— строковое значение ключа. Тогда элементы xsl:key
, включенные в преобразование, определяют множество всевозможных ключей обрабатываемого документа. Если этому множеству принадлежит ключ, состоящий из узла x
, имени у
и значения z
, говорят, что узел x
имеет ключ с именем у
и значением z
или что ключ у
узла x
равен z
.
Ключ src
из предыдущего примера определяет множество, которое состоит из следующих троек:
(< item name="A" .../>, 'src', 'a')
(< item name="B" .../>, 'src', 'b')
(< item name="C" .../>, 'src', 'a')
(< item name="D" .../>, 'src', 'c')
...
(< item name="H" .../>, 'src', 'a')
В соответствии с нашими определениями мы можем сказать, что элемент
имеет ключ с именем "src"
и значением "b"
или что ключ "src"
элемента
равен "a"
.
Для того чтобы обращаться к множествам узлов по значениям их ключей, в XSLT существует функция key
, о которой мы сейчас и поговорим.
Интервал:
Закладка: