» Главная
eXcode.ru » Статьи » Web » XSLT
» Новости
» Опросы
» Файлы
» Журнал



Пользователей: 0
Гостей: 22







Создание уникальных идентификаторов средствами XSLT




Автор: Bob DuCharme, 03 октября 2001
Оригинал статьи: XML.com
Перевод: В.Ярошевич, 16 ноября 2001


Когда вы при помощи таблицы стилей XSLT преобразуете один XML-документ в другой, возможность добавлять уникальные значения ID к элементам в результирующем документе позволяет сильно упростить его использование различными приложениями. Добавление такого идентификатора может, например, превратить каждый элемент в уникальный адрес для гиперссылок.

Функция XSLT generate-id() генерирует уникальный идентификатор для узла, указанного в аргументе. Этот идентификатор начинается с латинской буквы, так что вы можете использовать его как значение атрибута XML ID. Например, следующая таблица стилей копирует XML-документ и добавляет атрибут uid ("unique ID") к каждому элементу chapter, sect1 и sect2. Здесь инструкция xsl:value-of в первом шаблоне таблицы стилей использует функцию generate-id(), чтобы сгенерировать значение этих атрибутов.

<table class=code cellpadding=5 align=center width=98% border=1 bordercolor=#3B3B3B><tr><td>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>

<xsl:template match="chapter | sect1 | sect2">
<xsl:copy>
<xsl:attribute name="uid">
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
</td></tr></table>

При помощи этой таблицы стилей из такого XML-документа

<table class=code cellpadding=5 align=center width=98% border=1 bordercolor=#3B3B3B><tr><td>
<chapter>
<para>Then with expanded wings he steers his flight</para>
<figure><title>"Incumbent on the Dusky Air"</title>
<graphic fileref="pic1.jpg"/></figure>
<para>Aloft, incumbent on the dusky Air</para>
<sect1>
<para>That felt unusual weight, till on dry Land</para>
<figure><title>"He Lights"</title>
<graphic fileref="pic2.jpg"/></figure>
<para>He lights, if it were Land that ever burned</para>
<sect2>
<para>With solid, as the Lake with liquid fire</para>
<figure><title>"The Lake with Liquid Fire"</title>
<graphic fileref="pic3.jpg"/></figure>
</sect2>
</sect1>
</chapter>
</td></tr></table>

можно получить такой:

<table class=code cellpadding=5 align=center width=98% border=1 bordercolor=#3B3B3B><tr><td>
<chapter uid="N134711680">
<para>Then with expanded wings he steers his flight</para>
<figure><title>"Incumbent on the Dusky Air"</title>
<graphic fileref="pic1.jpg"/></figure>
<para>Aloft, incumbent on the dusky Air</para>
<sect1 uid="N134683456">
<para>That felt unusual weight, till on dry Land</para>
<figure><title>"He Lights"</title>
<graphic fileref="pic2.jpg"/></figure>
<para>He lights, if it were Land that ever burned</para>
<sect2 uid="N134684064">
<para>With solid, as the Lake with liquid fire</para>
<figure><title>"The Lake with Liquid Fire"</title>
<graphic fileref="pic3.jpg"/></figure>
</sect2>
</sect1>
</chapter>
</td></tr></table>

Ваш XSLT-процессор может генерировать различные значения с функцией generate-id(). Фактически, если вы запускаете такую же таблицу стилей с таким же документов на входе несколько раз, XSLT-процессор может каждый раз создавать значения идентификаторов, отличные от тех, что были сгенерированы во время первого прохода. Однако, если вы вызываете generate-id() более, чем один раз внутри одной таблицы стилей с одинаковым узлом в качестве аргумента, она каждый раз для этого узла сгенерирует одинаковые значения идентификатора. Так как уникальный идентификатор является популярным способом для организации гиперссылок, эта устойчивость функции generate-id() делает ее замечательным инструментом для решения подобных задач.

Например, мы можем копировать документ подобно тому, как это мы сделали выше, но при этом в начало результирующего документа добавить список всех иллюстраций (см. колонку "Transforming XML" на XML.com). Если же при этом предполагется, что конечный документ будет HTML-файлом, то мы можем использовать функцию generate-id для того, чтобы превратить каждую запись в таком списке иллюстраций в гиперссылку на элемент img в теле документа, непосредственно содержащим эту иллюстрацию:

<table class=code cellpadding=5 align=center width=98% border=1 bordercolor=#3B3B3B><tr><td>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="html"/>

<xsl:template match="chapter">
<html><body>

<!-- Формирование списка названий изображений,
в котором каждое название является ссылкой
на изображение в теле документа. -->
Pictures:<br/>
<xsl:for-each select="descendant::figure">
<a href="#{generate-id(graphic)}">
<xsl:value-of select="title"/></a><br/>
</xsl:for-each>

<xsl:apply-templates/>
</body></html>
</xsl:template>

<xsl:template match="para">
<p><xsl:apply-templates/></p>
</xsl:template>

<xsl:template match="graphic">
<!-- Изображение и название в виде подписи, по центру. -->
<center><a name="{generate-id(.)}"><img src="{@fileref}"/></a>
<xsl:value-of select="../title"/></center>
</xsl:template>

<!-- Блокировка вывода названия изображения,
так как оно уже добавлено в результирующее дерево
в шаблоне, соответствующем "graphic". -->
<xsl:template match="figure/title"/>

</xsl:stylesheet>
</td></tr></table>

С исходным документом, приведеным выше, и этой таблицей стилей XSLT-процессор может создать следующий HTML-документ:

<table class=code cellpadding=5 align=center width=98% border=1 bordercolor=#3B3B3B><tr><td>
<html>
<body>
Pictures:


<a href="#N134691840">"Incumbent on the Dusky Air"</a>


<a href="#N134692416">"He Lights"</a>


<a href="#N134757920">"The Lake with Liquid Fire"</a>


<p>Then with expanded wings he steers his flight</p>

<center>
<a name="N134691840"><img src="pic1.jpg"></a>
"Incumbent on the Dusky Air"
</center>
<p>Aloft, incumbent on the dusky Air</p>

<p>That felt unusual weight, till on dry Land</p>

<center>
<a name="N134692416"><img src="pic2.jpg"></a>
"He Lights"
</center>
<p>He lights, if it were Land that ever burned</p>

<p>With solid, as the Lake with liquid fire</p>

<center>
<a name="N134757920"><img src="pic3.jpg"></a>

"The Lake with Liquid Fire"
</center>


</body>
</html>
</td></tr></table>

(Для просмотра HTML-документа, вы должны использовать свои собственные файлы pic1.jpg, pic2.jpg и pic3.jpg.) В таблице стилей используется generate-id() дважды:

*

Инструкция xsl:for-each в шаблоне, соответствующем "chapter", добавляет значение title каждого элемента figure в результирующее дерево для формирования списка "Pictures:" в верхней части конечного документа. При этом содержание каждого из таких элементов title для создания ссылки на соответствующее изображение в теле документа размещается внутри HTML-элемента a. Непосредственно адрес ссылки указывается в атрибуте href каждого из таких элементов a. В нашем случае значение атрибута href начинается со знака "#" для обозначения того, что ссылка ведет на другой элемент a в самом документе, в котором значение атрибута name равно части строки после знака "#" в ссылке-источнике. Например, <a href="#a123"> указывает на элемент <a name="a123"> где-либо внутри документа.

Вместо строки "a123", определяющей каждый адрес ссылки, эта таблица стилей использует функцию generate-id() для создания идентификатора. Так как узел элемента graphic подается ей в качестве аргумента, функция создает идентифицирующую строку для каждого из трех элементов graphic: "N134691840", "N134692416" и "N134757920".
*

Для создания ссылки-адресата шаблон, соответствующий "graphic", размещает каждый HTML-элемент img в результирующем дереве внутри элемента a. Значение атрибутов src элементов img устанавливается значением атрибутов fileref элементов graphic исходного дерева, а элементы a используют функцию generate-id() для создания значений их атрибутов name. Указание в качестве аргумента к функции "." экивавалентно указанию self::node(), то есть текущего узла. В нашем случае это эквивалентно непосредственному указанию элементу узла graphic. Таким образом XSLT-процессор генерирует значение идентификатора для каждого узла graphic. Это те же самые три узла, что ранее использовали созданные generate-id() идентификаторы для ссылок, поэтому будут созданы такие же три значения: "N134691840", "N134692416" и "N134757920". Когда этот HTML-файл будет отображен в браузере, каждая ссылка в списке "Pictures:" теперь будет соответствовать изображению в документе.

Подведем итог. Устойчивость в данном контексте функции generate-id() при обработке конкретного узла, даже если функция генерирует идентификатор для этого узла более чем один раз, является ключевой. Элементы graphic не имели идентификаторов в исходном документе; с помощью это функции, их эквивалент в результирующем документе имеет их, и другие элементы в этом документе используют эти идентификаторы для связи с ними.
К началу статьи





Добавил: LedWormДата публикации: 2005-07-18 23:28:52
Рейтинг статьи:3.00 [Голосов 5]Кол-во просмотров: 5977

Комментарии читателей

Всего комментариев: 0
Ваше имя: *
Текст записи: *
Имя:

Пароль:



Регистрация

Каким почтовым клиентом вы пользуетесь?
Мышью
51% (83)
MS Outlook / Outlook Express
15% (25)
Eudora
0% (0)
Thunderbird
7% (12)
Веб-интерфейсом
20% (33)
Почта России
6% (9)

Проголосовало: 162
Ни что так не пугает мир. Как всем известный Дядя Билл!
Рейтинг: 2.2/10 (4)
Посмотреть все анекдоты

 
eXcode.ru » Статьи » Web » XSLT