Kniga-Online.club

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

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

 result-prefix="#default"/>

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

<xsl:namespace-alias

 stylesheet-prefix="#default"

 result-prefix="a"/>

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

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

<xsl:stylesheet

 version="1.0"

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

 xmlns:a="urn:a"

 xmlns="urn:b">

 <xsl:namespace-alias

  stylesheet-prefix="#default"

  result-prefix="a"/>

 <xsl:namespace-alias

  stylesheet-prefix="a"

  result-prefix="#default"/>

 <xsl:template match="root">

  <result>

   <a:element/>

  </result>

 </xsl:template>

</xsl:stylesheet>

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

<result xmlns="urn:a" xmlns:a="urn:b">

 <a:element/>

</result>

Результатом этого преобразования является то, что пространство имен с URI "urn:а" стало пространством имен по умолчанию, а пространство имен с URI "urn:b" изменило префикс на а.

В преобразованиях можно объявлять несколько псевдонимов пространств имен при условии, что одно и то же пространство имен преобразования не должно быть объявлено элементами xsl:namespace-alias с одинаковым порядком импорта псевдонимом для различных пространств имен выходящего документа.

Пример

Если преобразование a.xsl содержит определение

<xsl:namespace-alias

 stylesheet-prefix="x"

 result-prefix="a"/>

а преобразование b.xsl — определение

<xsl:namespace-alias

 stylesheet-prefix="x"

 result-prefix="b"/>

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

Совсем иначе обстоит дело с импортированием. При импортировании определения старших в порядке импорта преобразований могут переопределять определения младших преобразований. Таким образом, если преобразование a.xsl будет импортировать преобразование b.xsl, пространство имен x будет назначено псевдонимом пространству имен а и наоборот.

Ключи

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

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

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

Пусть входящий документ представляет собой список объектов (элементов item), каждый из которых имеет имя (атрибут name) и источник (атрибут source). Требуется сгруппировать объекты по своим источникам и получить документ приблизительно следующего вида.

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

<sources>

 <source name="a">

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

Первым шагом на пути решения этой задачи является формулировка в терминах XSLT предложения "сгруппировать объекты по своим источникам". Источник каждого объекта определяется его атрибутом source, значит множество объектов, принадлежащих одному источнику "а", будет определяться путем выборки

/items/item[@source='a']

Тогда для каждого элемента item в его группу войдут элементы, которые будут выбраны выражением

/items/item[@source=current()/@source]

Попробуем использовать этот факт в следующем шаблоне:

<xsl:template match="item">

 <source name="{@source}">

  <xsl:copy-of select="/items/item[@source=current()/@source]"/>

 </source>

</xsl:template>

Как и ожидалось, при применении этого правила к элементам item для каждого из них будет создана группа, принадлежащая тому же источнику, — уже хороший результат, но в условии требуется создать по группе не для каждого объекта, а для каждого источника. Чтобы достичь этого, можно создавать группу только для первого объекта, принадлежащего ей. Провести такую проверку опять же несложно: объект будет первым в группе тогда и только тогда, когда ему не предшествуют другие, элементы item, принадлежащие тому же источнику. Иначе говоря, создаем группы только для тех элементов, для которых выражение

preceding-sibling::item[@source-current()/@source]

будет возвращать пустое множество.

С небольшими добавлениями искомое преобразование целиком будет иметь вид.

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

<xsl:stylesheet

 version="1.0"

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

 <xsl:template match="items">

  <sources>

   <xsl:apply-templates/>

  </sources>

 </xsl:template>

 <xsl:template match="item">

  <xsl:choose>

   <xsl:when

    test="preceding-sibling::item[@source=current()/@source]"/>

   <xsl:otherwise>

    <source name="{@source}">

     <xsl:copy-of select="self::node()

      |following-sibling::item[@source=current()/@source]"/>

    </source>

   </xsl:otherwise>

  </xsl:choose>

 </xsl:template>

</xsl:stylesheet>

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

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

Проблема, которую мы подняли, достаточно серьезна. Она состоит в оптимизации поиска узлов с определенными свойствами в древовидно организованной структуре.

Попробуем разобраться в смысле фразы "узел обладает определенными свойствами". Очевидно, это означает, что для этого узла выполняется некое логическое условие, иначе говоря, некий предикат обращается в "истину".

Однако какого именно типа условия мы чаще всего проверяем? Анализируя различные классы задач, можно придти к выводу, что в большинстве случаев предикаты являются равенствами — выражениями, которые обращаются в "истину" тогда и только тогда, когда некоторый параметр узла, не зависящий от текущего контекста, равен определенному значению. В нашем примере смысл предиката на самом деле состоит не в том, чтобы проверить на истинность выражение @source=current()/@source, а в том, чтобы проверить на равенство @source и current()/@source.

Если переформулировать это для общего случая, то нам нужно выбрать не те узлы, для которых истинно выражение A=B, скорее нужно выбрать те, для которых значение A равно значению B. Иначе говоря, узел будет идентифицироваться значением в своего свойства A. И если мы заранее вычислим значения свойств A, проблема поиска узлов в дереве сведется к классической проблеме поиска элементов множества (в нашем случае — узлов дерева) по определенным значениям ключей (в нашем случае — значениями свойств A).

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

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

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

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


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

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


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

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

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


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