Вход/Регистрация
Технология XSLT
вернуться

Валиков Алексей Н.

Шрифт:

</items>

нужно было получить документ вида.

Листинг 11.2. Требуемый результат

<sources>

 <source name="а">

<item source="a" name="A"/>

<item source="a" name="C"/>

<item source="a" name="H"/>

 </source>

 <source name="b">

<item source="b" name="B"/>

<item source="b" name="E"/>

<item source="b" name="F"/>

 </source>

 <source name="c">

<item source="c" name="D"/>

<item source="c" name="G"/>

 </source>

</sources>

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

item
по значениям одного из своих атрибутов.

Напомним вкратце решение, которое было тогда предложено. При обработке первого объекта каждой группы мы создавали элемент

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

preceding-sibling::item[@source=current/@source]

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

В этом разделе мы приведем гораздо более эффективное и остроумное решение задачи группировки, впервые предложенное Стивом Мюнхом (Steve Muench), техническим гуру из Oracle Corporation. Оно основывается на двух посылках.

□ Мы можем выбрать множество узлов по их свойствам при помощи ключей.

□ Мы можем установить, является ли узел первым узлом множества в порядке просмотра документа при помощи функции

generate-id
.

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

generate-id
вроде бы предназначена только для генерации уникальных значений.

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

generate-id
возвращает уникальный идентификатор первого в порядке просмотра документа узла переданного ей множества. Значит для того, чтобы проверить, является ли некий узел первым узлом группы, достаточно сравнить его уникальный идентификатор со значением выражения
generate-id($group)
, где
$group
— множество узлов этой группы.

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

Листинг 11.3. Группирующее преобразование

<xsl:stylesheet

 version="1.0"

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

 <xsl:key name="src" match="item" use="@source"/>

 <xsl:template match="items">

<sources>

<xsl:apply-templates

select="item[generate-id(.)=generate-id(key('src', @source))]"/>

</sources>

 </xsl:template>

 <xsl:template match="item">

<source name="{@source}">

<xsl:copy-of select="key('src', @source)"/>

</source>

 </xsl:template>

</xsl:stylesheet>

Результат выполнения этого преобразования уже был приведен в листинге 11.2.

Перечисление узлов

Функции

name
и
local-name
предоставляют возможности для работы с документом, имена элементов и атрибутов в котором заранее неизвестны. Например, если шаблон определен как:

<xsl:template match="*[starts-with(local-name, 'чеб')]">

  • Читать дальше
  • 1
  • ...
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: