Kniga-Online.club

Алексей Валиков - Технология XSLT

Читать бесплатно Алексей Валиков - Технология XSLT. Жанр: Программирование издательство -, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

<items>

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

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

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

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

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

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

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

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

</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(), 'чеб')]">

 ...

</xsl:template>

то обрабатываться им будут все элементы, локальные части имен которых начинаются на "чеб" (например, "чебуреки", "Чебоксары", "чебурашка").

Следующее преобразование демонстрирует, как при помощи функции local-name и ключей сосчитать количество элементов и атрибутов документа с различными именами.

Листинг 11.4. Входящий документ

<foo bar="1">

 <bar foo="2"/>

 <bar bar="3"/>

 <foo foo="4">

  <bar bar="5"/>

  <bar foo="6"/>

 </foo>

</foo>

Листинг 11.5. Преобразование

<xsl:stylesheet

 version="1.0"

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

 <!-- Выводим информацию в текстовом виде -->

 <xsl:output method="text"/>

 <!--

  | Создаем ключ, отображающий узлы атрибутов и элементов

  | в их локальные части имен.

  +-->

 <xsl:key name="node" match="*" use="local-name()"/>

 <xsl:key name="node" match="@*" use="local-name()"/>

 <xsl:template match="*|@*">

  <xsl:variable name="name" select="local-name()"/>

  <!--

   | Если узел является первым узлом группы (первым встретившимся

   | узлом документа с данным именем), выводим информацию о

   | количестве узлов в группе (количество узлов с таким же именем).

   +-->

  <xsl:if test="generate-id(.) = generate-id(key('node', $name))">

   <xsl:text>Node '</xsl:text>

   <xsl:value-of select="local-name()"/>

   <xsl:text>' found </xsl:text>

   <xsl:value-of select="count(key('node', $name))"/>

   <xsl:text> times.&#xA;</xsl:text>

  </xsl:if>

  <!-- Рекурсивно обрабатываем дочерний элемент и атрибуты -->

  <xsl:apply-templates select="*|@*"/>

 </xsl:template>

</xsl:stylesheet>

Листинг 11.6. Выходящий документ

Node 'foo' found 5 times.

Node 'bar' found 7 times.

Именованный шаблон как функция

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

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

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

Использование именованных шаблонов как функций обуславливается следующими тезисами.

□ Именованный шаблон можно вызывать вне зависимости от того, какая часть документа обрабатывается в данный момент.

□ Именованному шаблону можно передавать параметры.

□ Результат выполнения именованного шаблона можно присваивать переменной.

Вызов именованного шаблона выполняется элементом xsl:call-template, в атрибуте name которого указывается имя вызываемого шаблона. Такой вызов не зависит от того, какая часть документа обрабатывается в данный момент и может производиться по необходимости.

Параметры именованному шаблону передаются точно так же, как и обычному — при помощи элементов xsl:with-param, которые могут быть включены в вызывающий элемент xsl:call-template. Примером вызова именованного шаблона с параметрами может быть конструкция вида

<xsl:call-template name="foo">

 <xsl:with-param name="x" select="1"/>

 <xsl:with-param name="y" select="2"/>

</xsl:call-template>

которая вызывает шаблон с именем foo и передает ему параметр x со значением, равным 1 и параметр y со значением, равным 2.

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

Пример

В качестве примера приведем простой шаблон, который вычисляет квадрат переданного ему параметра x:

<xsl:template name="sqr">

 <xsl:param name="x"/>

 <xsl:value-of select="$x * $x"/>

</xsl:template>

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

<xsl:variable name="y">

 <xsl:call-template name="sqr">

Перейти на страницу:

Алексей Валиков читать все книги автора по порядку

Алексей Валиков - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Технология XSLT отзывы

Отзывы читателей о книге Технология XSLT, автор: Алексей Валиков. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*