Применение языка XSL для отображения БД НИКА.
Аннотация
В статье рассматривается язык XSL как схема данных для динамически созданных XML-документов, содержащих фрагменты ООБД НИКА. Описываются элементы языка XSL и язык выражений XPath, используемый в XSL, приводятся соответствующие примеры для иллюстрации работы этих элементов на основе введенного в данной статье элемента list (список). Далее рассматриваются различные подходы для построения отображения вершин ООБД НИКА. Любой из описанных подходов должен включать в себя основные методы отображения вершин, описанных в работе [8]. Первый подход основан непосредственно на элементе list, соответствующему иерархическому списку, и на элементе table, соответствующему двумерной таблице (элемент table в данной статье не рассматривается). Второй, более общий, подход включает в себя первый и представляет собой отображение иерархии ООБД НИКА в виде, который соответствует dcm-файлу [5]. Третий подход использует язык XSL для расширения возможностей языка HTML. В заключении приводится сравнение описанных подходов.
Введение
Язык XSL (extensable stylesheet language) [6,7] состоит из следующих компонент XSLT преобразование (XSL transformations) xml-элементов в другие xml-элементы, которые определяются заданным пространством имен, язык выражений XML path language (XPath), используемый XSLT, а также объекты форматирования, представляющие собой развитие ранее определенных стандартов стилей для xml и html класса CSS (cascading style sheet). Частным случаем XSL преобразования является преобразование xml-элементов в html-элементы. XSL включает в себя возможности языка SGML [1] описания типа данных (data type definition - DTD) на более низком уровне общности и определяет способы отображения элементов. Это позволяет использовать XSL для определения структуры новых элементов на основе уже определенных элементов, html-элементов и строк. Совокупность определенных элементов в виде xsl-шаблонов представляет собой тип xml-документа. Таким образом иерархия xsl-элементов может рассматриваться как схема xml-документа. Такая модель может быть хорошо использована для отображения вершин БД НИКА [10]. Ранее при отображении использовался язык HTML [3] , в котором отсутствовала схема данных [2]. Поскольку БД НИКА имеет схему данных, то новая модель с использованием xsl-схемы является более предпочтительной, чем html-документ. Фрагмент БД НИКА отображается в xml-документ, к которому применяется "стандартный" xsl-шаблон или xsl-шаблон, определенный пользователем. Преимущества схемы данных для объектно-ориентированного языка разметки OOML указываются в [4] (хотя назначения OOML и XSL различно): логическая и физическая независимость данных, использование модели данных, интероперабельность, поддержка целостности. Конечным результатом применения xsl-преобразований к xml-документу для показа через стандартную программу просмотра, как и в первоначальной модели, является html-документ.
В данной статье описываются xsl-элементы и их использование для отображения вершин СУБД НИКА. При этом не ставится задача составить и описать полную xsl-схему, но выделить основные способы ее построения. Наиболее общим видом xml-файла, динамически созданного посредством cgi-скрипта из БД НИКА, является вид, в котором названия элементов - это имена вершин БД и нетерминальные вершины отображаются в элементы, содержащие в себе подчиненные элементы, а терминальные вершины отображаются в соответствующие элементы, содержащие значения этих вершин. Такой вид соответствует виду dcm-файла, содержащего фрагмент БД НИКА, и используемого в макетном редакторе МАГИС [5]. Другим видом xml-файла, полученного из СУБД НИКА, является вид с использованием введенного в данной статье элемента list (список), определенного посредством стандартных элементов xsl. Элемент list отображает вершины БД НИКА в виде списка или иерархического списка (посредством вложенных элементов ul для формирования html-документа) и имеет атрибуты для управления отображением элементов на экране.
Описание стандартных элементов языка XSL.
Описание элементов составлено на основе документаций по языку XSL [6,7]. Для пояснения работы элементов были составлены примеры. 1. <xsl:import>
Аттрибут: href.
Загружает дополнительную шаблоны из xsl-файла по ссылке href.
Пример:
<xsl:import href="dbverts. xsl"/> <!-- загружает шаблоны для показа xml-элементов в виде иерархического списка -->
...
<xsl:template match="hierarchy_view"> <!-- шаблон для выбора способа отображения в виде html или xml -->
<xsl:choose>
<xsl:when test="@type='html'">
<xsl:apply-templates/> <!-- в случае html-отображения (параметр type=html) применяет шаблоны, описанные в данном xsl-файле -->
</xsl:when>
<xsl:when test="@type='xml'">
<xsl:apply-imports/> <!-- в случае xml-отображения (параметр type=xsl) применяет шаблоны, описанные в файле dbverts.xsl -->
</xsl:when>
<xsl:otherwise>
error in parameter type
</xsl:otherwise>
</xsl:choose>
</xsl:template>
...
2. <xsl:include>
Аттрибут: href.
Дополняет текущую стилевую таблицу из xsl-файла по ссылке href.
3. <xsl:preserve-space>
Аттрибут: elements.
Содержит в параметре elements список элементов исходной иерархии элементов, в которых введенные пробелы должны быть сохранены.
Выражения namespace:* и * могут быть использованы для обозначения всех элементов из пространства имен namespace или из данного пространства имен.
4. <xsl:strip-space>
Аттрибут: elements.
Элемент обратный к <xsl:preserve-space>. Параметр elements содержит список элементов, в которых должны быть опущены введенные пробелы.
Пример:
...
<xsl:strip-space elements="doc chapter section"/> <!-- опускает пробелы в элементах doc, chapter, section -->
<xsl:output method="html" indent="yes" encoding="koi8-r"/> <!-- определяет метод отображения -->
<xsl:template match="doc">
<html>
<head>
<title>
<xsl:value-of select="title"/>
</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
...
5. <xsl:output>
Атрибуты: method, version, encoding, omit-xml-declaration, standalone, doctype-public,
doctype-system, cdata-section-elements, indent, media-type.
Управление результатом применения данного xsl-шаблона к xml-файлу. Является элементом верхнего уровня.
Тип элементов, получаемых в результате применения, указывается в атрибуте method ={ "xml" | "html" | "text" }с версией version в кодировке encoding. omit-xml-declaration = "yes" - не выдавать в результате отображения строку объявления <?xml...?>; standalone = "yes" ("no") - определяет, будет ли включено в вывод отдельное объявление XML, и если да - устанавливает его значение; doctype-public, doctype-system - используются в объявлении <!DOCTYPE>; cdata-section-elements - задает имена тех элементов, содержимое которых должно выводиться как разделы CDATA; indent = "yes" - добавляет дополнительные пробелы в результирующее дерево для улучшения читаемости выдаваемых элементов; media-type - задает тип MIME вывода. Пример см. в элементе <xsl:strip-space>.
6. <xsl:namespace-alias>
Атрибуты: stylesheet-prefix, result-prefix.
Заменяет префикс stylesheet-prefix пространства имен в результирующем дереве на префикс result-prefix.
7. <xsl:apply-imports>
Обрабатывает контекстный узел с шаблоном из импортированного xsl-файла. Используется совместно с элементом <xsl:import>. Пример см. в элементе <xsl:import>.
8. <xsl:attribute-set>
Атрибуты: name, use-attribute-sets.
Содержимое: элементы <xsl:attribute>.
Определяет множество атрибутов с названием name и атрибутов, добавляемых в данное множество из списка имен множеств атрибутов, задаваемого в атрибуте use-attribute-sets. Является элементом верхнего уровня.
9. <xsl:comment>
Содержимое: шаблон.
Добавляет xml-комментарий в результирующее дерево.
10. <xsl:processing-instruction>
Атрибут: name.
Содержимое: шаблон template.
Добавляет xml-инструкцию с названием name в результирующее дерево (поскольку в случае прямого указания инструции при выводе в шаблоне она будет проигнорирована).
11. <xsl:stylesheet>
Атрибуты: id, extension-element-prefixes, exclude-result-prefixes, version
Содержимое: элементы верхнего уровня.
Определяет xsl-документ и является верхним xsl-элементом, содержащим все остальные элементы в документе.
Атрибут id может определять уникальный идентификатор; extension-element-prefixes - список префиксов пространств имен, которые являются расширенными префиксами элементов; exclude-result-prefixes - список префиксов пространств имен, которые не должны быть отображены в результирующее дерево; version - используемая версия XSLT.
Пример: ulist.xsl
<xsl:stylesheet xmlns:xsl="http://www. w3.org/1999/XSL/Transform" version="1.0"> <!-- начало определения xsl-файла, содержащего --> <!-- определение префикса xsl со ссылкой на используемое пространство имен для преобразования в html -->
<xsl:template match="doc"> <!-- верхний xml-элемент doc -->
<html>
<body>
<h3>Complete example of xsl-document (ulist. xsl) with data in ulist. xml</h3>
<xsl:apply-templates/> <!-- позволяет использовать любые шаблоны в шаблоне doc -->
</body>
</html>
</xsl:template>
<xsl:template match="list"> <!-- элемент список list -->
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</ul>
</xsl:template>
<xsl:template match="el"> <!-- элемент el - элемент в списке list -->
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
</xsl:stylesheet>
ulist. xml
<?xml version="1.0" encoding="windows-1251"?> <!-- версия xml и используемая кодировка символов (например, koi8-r, cp-866 и т. д.) -->
<?xml-stylesheet href="ulist. xsl" type="text/xsl"?> <!-- ссылка в виде url на xsl-файл, определяющий используемые элементы -->
<doc> <!-- данные -->
<list>
<el>elem 1</el>
<el>elem 1</el>
<el>elem 3</el>
<el>elem 4
<list>
<el>elem 4.1</el>
<el>elem 4.3</el>
<el>elem 4.3</el>
</list>
</el>
<el>elem 5</el>
</list>
</doc>
12. <xsl:transform>
Выполняет теже самые функции, что и элемент xsl:stylesheet.
13. <xsl:template>
Атрибуты: match, name, priority, mode.
Содержимое: любые xsl-элементы (кроме тех, которые являются только элементами верхнего уровня, как, например, xsl:output) и элементы, определенные в используемых пространствах имен, заданных в верхнем элементе xsl:stylesheet.
Может быть только элементом верхнего уровня. Определяет xsl-шаблон для xml-элементов, задаваемых выражением в атрибуте match. В этом случае данный шаблон может быть использован другими шаблонами посредством элемента xsl:apply-templates. Для разрешения конфликтов между различными шаблонами, которым подходят одни и теже элементы, может быть задан атрибут приоритета priority. Для различного использования шаблона в разных контекстах может быть задан параметр режим использования mode. Атрибут name задает название шаблона и при этом атрибут match не должен быть задан. Такой шаблон вызывается явно другими шаблонами посредством элемента xsl:call-template.
Пример: (модификация примера, приведенного в описании элемента xsl:stylesheet)
<xsl:template match="list"> <!-- шаблон для xml-элемента список list -->
<xsl:choose> <!-- выбор значений атрибута kind -->
<xsl:when test="@kind='unordered'"> <!-- в случае значения 'unordered' - ненумерованный список -->
<ul>
<xsl:call-template name="list"/> <!-- вызывает шаблон с именем list -->
</ul>
</xsl:when>
<xsl:when test="@kind='ordered'"> <!-- в случае значения 'ordered' - нумерованный список -->
<ol>
<xsl:call-template name="list"/> <!-- вызывает шаблон с именем list -->
</ol>
</xsl:when>
<xsl:otherwise>
<p>wrong attribute <b>kind</b></p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="list"> <!-- шаблон с именем list (отличный от шаблона элемента) -->
<xsl:if test="@title">
<li>
<big><xsl:value-of select="@title"/></big> <!-- печатает значение атрибута заголовок списка title как первый элемент списка -->
</li>
</xsl:if>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</xsl:template>
<xsl:template match="el"> <!-- элемент el - элемент в списке list -->
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
В xml-файле необходимо задать значения для атрибута kind
<list kind="unordered">
...
<list kind="ordered" title="Ordered list">
...
</list>
...
</list>
14. <xsl:apply-templates>
Атрибуты: select, mode.
Содержимое: ноль или более элементов xsl:sort, xsl:with-param; может быть пустым.
В атрибуте select задаютя шаблоны, которые могут быть использованы в текущем шаблоне. Атрибут mode (см. описание xsl:template) задает режим (контекст) использования шаблона, указанного в атрибуте select.
Пример: (модификация примера, приведенного в описании элемента xsl:stylesheet)
<xsl:template match="doc"> <!-- верхний xml-элемент doc -->
<html>
<body>
<xsl:apply-templates select="list" mode="mainlist"/> <!-- позволяет использовать шаблоны list с режимом mainlist в шаблоне doc -->
</body>
</html>
</xsl:template>
<xsl:template match="list" mode="mainlist"> <!-- элемент основной список list (режим mainlist) -->
<p>
<h3>Elements list</h3>
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</ul>
</p>
</xsl:template>
<xsl:template match="list"> <!-- элемент список list -->
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</ul>
</xsl:template>
<xsl:template match="el"> <!-- элемент el - элемент в списке list -->
<li>
<xsl:apply-templates/>
</li>
</xsl:template>
15. <xsl:for-each>
Атрибут: select.
Содержимое: любой допустимый элемент.
Обрабатывает в цикле каждый узел, задаваемый выражением в атрибуте select.
Пример: (модификация примера, приведенного в описании элемента xsl:stylesheet)
<xsl:template match="list"> <!-- элемент список list -->
<ul>
<xsl:for-each select="el"> <!-- цикл для каждого элемента списка el -->
[<xsl:value-of select="position()"/>] <!-- печать номера текущего элемента -->
<xsl:apply-templates/><br/> <!-- обработка текущего элемента list -->
</xsl:for-each>
</ul>
</xsl:template>
16. <xsl:call-template>
Атрибут: name.
Содержимое: элементы xsl:with-param.
Позволяет явно вызвать из одного шаблона другой с указанием имени шаблона name.
Пример см. xsl:template.
17. <xsl:param>
Атрибуты: name, select.
Содержимое: шаблон template.
Задает переменную в данном шаблоне или для нескольких шаблонов, если используется как элемент верхнего уровня. Подобен элементу xsl:variable. В случае использования внутри шаблона xsl:template может задавать параметры к шаблону, указываемые при вызове этого шаблона из другого посредством xsl:call-template.
Пример:(модификация примера, приведенного в описании элемента xsl:template)
<xsl:template match="list">
<xsl:variable name="ttl"> <!-- переменная ttl принимает значение атрибута title, если он задан и -->
<xsl:choose> <!-- строковое значение 'List' в противном случае -->
<xsl:when test="@title">
<xsl:value-of select="@title"/>
</xsl:when>
<xsl:otherwise>
List
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="list"/> <!-- вызов шаблона с именем list с параметром title, равным переменной ttl -->
<xsl:with-param name="title" select="$ttl"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="list">
<xsl:param name="title"/> <!-- принимает значение переданного параметра title при вызове шаблона -->
<xsl:if test="$title">
<br/>title:<big><xsl:value-of select="$title"/></big> <!-- печатает заголовок списка title-->
</xsl:if>
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</ul>
</xsl:template>
18. <xsl:with-param>
Атрибуты: name, select.
Содержимое: шаблон template.
Задает значение параметра с именем name и значением select для вызываемого шаблона с помощью xsl:call-template. Используется внутри элементов xsl:call-template, xsl:apply-templates. Пример см. xsl:param.
19. <xsl:text>
Атрибуты: disable-output-escaping
Содержимое: текст.
Добавляет обычный текст в результирующее дерево. Атрибут disable-output-escaping="yes" указывает, что специальные символы (такие как "<") должны выводиться как есть, а не с использованием принятой формы "<" (начальное значение "no").
20. <xsl:copy>
Атрибут: use-attribute-sets.
Содержимое: шаблон template.
Копирует текущий узел в результирующее дерево без атрибутов и подчиненных элементов.
21. <xsl:copy-of>
Атрибут: select.
Содержимое: шаблон template.
Добавляет множество узлов, заданных выражением select, в результирующее дерево с атрибутами и подчиненными элементами.
В отличии от xsl:value-of не переводит результат выражения select в строковое значение. Пример см. xsl:element.
22. <xsl:value-of>
Атрибуты: select, disable-output-escaping.
Добавляет строковое значение выражения, заданного атрибутом select, в результирующее дерево. Атрибут disable-output-escaping см. в xsl:text.
Пример см. xsl:for-each.
23. <xsl:element>
Атрибуты: name, namespace, use-attribute-sets.
Содержимое: шаблон template.
Добавляет динамически элемент с именем name, ссылкой на пространство имен namespace для этого элемента и множеством атрибутов
use-attribute-sets.
Пример: (добавление к примеру, приведенного в описании элемента xsl:param)
<!-- данный шаблон выполняет копирование элементов и их атрибутов из исходного дерева в результирующее
и позволяет, например, использовать html-элементы в исходном xml-файле -->
<xsl:template match="*"> <!-- шаблон, которому подходит любой исходный элемент -->
<xsl:variable name="elem_name" select="name(current())"/> <!-- переменная, равная имени текущего элемента -->
<xsl:element name="{$elem_name}"> <!-- определяет элемент, совпадающий с текущим -->
<xsl:copy-of select="@*"/> <!-- копирует атрибуты в результирующий элемент -->
<xsl:apply-templates/> <!-- позволяет использовать любой шаблон внутри данного элемента -->
</xsl:element>
</xsl:template>
ulist. xml
<?xml version="1.0"?>
<?xml-stylesheet href="ulist. xsl" type="text/xsl"?> <!-- ссылка в виде url на xsl-файл, определяющий используемые элементы -->
<doc> <!-- данные -->
<list>
<el>elem 1</el>
<el>elem 1</el>
<el><font size="3" color="red"><b>elem 3</b></font></el> <!-- используются html-элементы "font" и "b" -->
<el>elem 4
<list>
<el><h1>elem 4.1</h1></el> <!-- используются html-элемент "h1" -->
<el>elem 4.3</el>
<el>elem 4.3</el>
</list>
</el>
<el>elem 5</el>
</list>
</doc>
24. <xsl:attribute>
Атрибуты: name, namespace.
Содержимое: шаблон template.
Позволяет динамически добавлять атрибуты для данного элемента. Имя атрибута задается посредством name, и namespace задает ссылку на пространство имен для данного атрибута.
<xsl:template match="list">
<br/>
<font>
<xsl:choose>
<xsl:when test="@title"> <!-- задан атрибут заголовок -->
<xsl:attribute name="size">+1</xsl:attribute> <!-- добавляет атрибут size для текущего элемента font -->
<xsl:value-of select="@title"/>
</xsl:when>
<xsl:otherwise> <!-- атрибут заголовок опущен -->
<xsl:attribute name="color">blue</xsl:attribute> <!-- добавляет атрибут color для текущего элемента font -->
List
</xsl:otherwise>
</xsl:choose>
</font>
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
</ul>
</xsl:template>
25. <xsl:if>
Атрибут: test.
Содержимое: шаблон template.
Содержимое элемента добавляется в результирующее дерево в случае истинности выражения, задаваемого атрибутом test. В противном случае содержимое xsl:if пропускается. Пример см. элементы xsl:template, xsl:param.
26. <xsl:choose>
Содержимое: один или более элементов xsl:when и ноль или один элемент xsl:otherwise.
Содержимое первого элемента xsl:when, у которого значение выражения атрибута test равно true, добавляется в результирующее дерево. Если такого элемента xsl:when не существует, то добавляется содержимое элемента xsl:otherwise. Пример см. элементы xsl:template, xsl:param.
27. <xsl:when>
Атрибут: test.
Содержимое: шаблон template.
Элемент xsl:when - это часть выражения xsl:choose. Если значение выражения атрибута test равно true, то содержимое элемента добавляется в результирующее дерево. Пример см. элементы xsl:template, xsl:param.
28. <xsl:otherwise>
Атрибут: test.
Содержимое: шаблон template.
Элемент xsl:otherwise - это часть выражения xsl:choose. Если значение атрибута test ни у одного элемента xsl:when не равно true, то содержимое элемента xsl:otherwise добавляется в результирующее дерево. Пример см. элементы xsl:template, xsl:param.
29. <xsl:message>
Атрибут: terminate
Содержимое: шаблон template.
Элемент для отображения сообщения для пользователя. Если атрибут terminate равен yes, то выполнение данного xsl-файла будет завершено сразу после отображения сообщения (если равен no, то выполнение не будет завершено).
30. <xsl:variable>
Атрибут: name, select.
Содержимое: шаблон template.
Задает переменную с именем name, равной значению выражения select. Может быть элементом верхнего уровня.
31. <xsl:sort>
Атрибуты: .select, lang, data-type, order, case-order.
Элемент не содержит других элементов. Является содержимым элементов xsl:apply-templates, xsl:for-each. Сортирует множество узлов, задаваемых выражением select элемента xsl:apply-templates. Атрибут select задает выражение, вычисляемое для каждого узла из сортируемого множества. Атрибут lang задает язык и используется при сортировке. Атрибут data-type задает тип сортируемых данных ("text", "number", или тип, определенный пользователем). Атрибут order задает порядок сортировки по возрастанию ("ascending") или по убыванию ("descending"). Атрибут case-order задает порядок сортировки для заглавных и строчных букв. В случае значения "upper-first" вначале сортируются заглавные буквы и затем строчные, в случае значения "lower-first" - наоборот. Сортировка может задаваться сразу по нескольким полям. Для этого необходимо задать для каждого поля (элемента) отдельное выражение xsl:sort. Каждое последующее поле является вторичным по отношению к предыдущим полям и сортируется в зависимости от них.
Пример:
<xsl:template match="list"> <!-- элемент список list -->
<ul>
<xsl:apply-templates select="el"/> <!-- позволяет использовать шаблоны el в шаблоне list -->
<xsl:sort select="." data-type="number" order="ascending"/> <!-- сортирует элементы el списка list, которые являются числами, -->
</xsl:apply-templates> <!-- по возрастанию -->
</ul>
</xsl:template>
32. <xsl:number>
Атрибуты: level, count, from, number, format, lang, letter-value, grouping-separator, grouping-size.
Элемент не содержит других элементов. Вычисляет количество элементов в исходном дереве или вычисляет числовое выражение, задаваемое атрибутом value и добавляет текстовое представление результата в результирующее дерево. Атрибут level определяет уровень подсчета (single, multiple, any). Атрибут count определяет элементы для подсчета. Атрибут from задает шаблон для определения начала подсчета элементов. Атрибут number задает числовое выражение для преобразования его в текстовое представление. Атрибут format задает формат для текстового представления числа, lang - используемый язык, letter-value - выбирает буквы алфавита (alphabetic) или традиционные (traditional), grouping-separator - символ разделителя для групп (","), grouping-size - число цифр в группе (3).
33. <xsl:decimal-format>
Атрибуты: name, decimal-separator, grouping-separator, infinity, minus-sign, NaN, percent, per-mille, zero-digit, digit, pattern-separator.
Элемент не содержит других элементов и является элементом верхнего уровня. Определяет десятичный формат для преобразования числа в текст. Необязательный атрибут name задает название данного формата для возможности ссылаться на него. В случае, если атрибут name не задан, используется как формат по умолчанию. Атрибут decimal-separator определяет символ десятичного разделителя ("."), grouping-separator - разделитель групп (","), infinity - строка представления математической бесконечности (infinity), minus-sign - символ для преставления отрицательных чисел ("-"), NaN - строка для представления, когда выражение не является числом (NaN), percent- символ процента ("%"),
per-mille - символ ‰ ("‰"), zero-digit - символ используется в строке форматирования для представления числа, когда пропускаемые цифры должны быть показаны в виде этого символа ("0"), digit - символ исользуется в строке форматирования для представления числа, где пропускаемые цифры будут отсутствовать ("#"), pattern-separator - символ разделителя строк форматирования (";").
34. <xsl:key>
Атрибуты: name, match, use.
Элемент не содержит других элементов и является элементом верхнего уровня. Ключи могут быть определены для быстрого доступа к элементам и служат в языке XSL обобщением механизма id/idref для обозначения элементов в XML. Элемент определяет ключ для последующего использования с функцией node-set key(name, object), которая возвращает узлы, соответствующие объекту object в определенном ключе name. Атрибут name задает имя ключа, match определяет узлы, для которых устанавливается этот ключ, use задает выражение для каждого узла, которое определяет этот ключ.
35. <xsl:fallback>
Содержимое: шаблон template.
Содержимое элемента xsl:fallbаck вычисляется и добавляется в результирующее дерево, когда содержимое текущего элемента не может быть интерпретировано. Используется в элементах, являющихся расширением XSLT.
XPath
XSLT описывает шаблоны посредством языка XML Path (XPath):
- XPath имеет сокращенный и расширенный синтаксисы;
- XPath определяет грамматику путей нахождения различных частей документа или документов (основное назначение);
- Исходной моделью для XPath служит общий синтаксис файловой системы "path/file".
Кроме того, он обеспечивает основные возможности для манипулирования строками, числами и булеанами. XPath использует компактный синтаксис, отличный от XML, для упрощения работы с http-идентификаторами ресурсов (URI) и значениями атрибутов XML. XPath оперирует с абстрактной логической структурой XML документа и получает имя из пути как в URL для прохода через иерархическую структуру XML документа. При адресации XPath может быть использован для проверки на совпадения, например, совпадает или нет узел с заданным шаблоном. XPath представляет XML документ как дерево узлов. Существуют различные типы узлов, включая узлы элементов, узлы атрибутов и текстовые узлы. XPath определяет способ вычисления строкового значения для каждого типа узла. Некоторые типы узлов также имеют имена. XPath полностью поддерживает пространства имен XML. Таким образом имя узла представляет собой пару, состоящую из локальной части и возможно нулевого http-идентификатора ресурсов пространства имен.
Шаблоны XSL имеют контекст. XPath выражения и XSLT элементы могут изменять текущий контекст и следование соответствующих узлов. XPath является полным, он адресует все подходящие элементы. Необходимо использовать предикаты для уточнения множества выбранных узлов. Предикаты следуют в квадратных скобках после названия элемента. Ссылка на элементы, подходящие данному шаблону, определяется атрибутом match элемента template. Пример: <xsl:template match="section/title[1]"> - шаблону будет соответствовать первый элемент <title>, подчиненный всем элементам <section> в данном контексте. Выражения предикатов могут быть сложными и более или менее произвольными. Выражения могут содержать логические операции and, or, not.
Синтаксис шаблона XPath описывается формально в спецификаации XPath. Абстрактная, но менее формальная харатеристика синтаксиса:
- шаблон XPath есть путь нахождения "location path", который является абсолютным, если
начинается со слеша ("/"), и относительным в противном случае;
- относительный путь состоит из последовательности шагов, разделенных слешами;
- шаг - это есть описатель, условие для узла и предикат.
Формальный синтаксис становится более завершенным, посредством того, что он должен быть описан как сокращенным, так и несокращенным синтаксисами.
Некоторые примеры путей XPath с использованием сокращенного синтаксиса:
- para выбирает para элемент, подчиненный контекстному узлу;
- * - все элементы, подчиненные контекстному узлу;
- text() - все текстовые узлы, подчиненные контекстному узлу;
- @value выбирает атрибут value контекстного узла;
- @* - все атрибуты контекстного узла;
- para[1] - первый элемент para, подчиненный контекстному узлу;
- para[last()] - последний элемент para, подчиненный контекстному узлу;
- */para выбирает все элементы para, подчиненные узлам, которые являются подчиненными контекстному узлу;
- /doc/chapter[5]/section[2] выбирает второй элемент section пятого элемента chapter в элементе doc;
- chapter//para выбирает все подчиненные chapter элементы para;
- //para выбирает все элементы para, подчиненные нулевому узлу документа;
- //olist/item выбирает все элементы item, подчиненные olist, в том же документе, что и контекстный узел;
- . выбирает контекстный узел;
- .//para выбирает элементы para, подчиненные контекстному узлу (в том числе и узлы, которые не непосредственно подчинненые);
- .. выбирает узел, которому подчинен контекстный;
- ../@lang выбирает атрибут lang узла, которому подчинен контекстный;
- para[5][@type="warning"] выбирает пятый элемент para, подчиненный контекстному, и, который имеет атрибут type со значением warning.
- chapter[title="introduction"] выбирает элемент chapter, подчиненный контекстному, который имеет один или более подчиненных элементов title, содержание которых представляет собой строковое значение, равное introduction.
- chapter[@fontsize and @align] выбирает все элементы chapter, подчиненные контекстному, который имеет атрибуты fontsize и align.
Для доступа к узлам дерева элементов в XPath используются описатели. На схеме показаны описатели для обращения к узлам различных уровней дерева относительно выделенного текущего узла, отмеченного жирной линией.

Несокращенный синтаксис XPath использует описатели, показанные на схеме, т. е.
для обращения к элементам para, которым подчинен текущий элемент, используется выражение ancestor::para; для обращения к атрибуту type используется выражение
attribute::type (или в сокращенном варианте @type).
Необходимо отметить, что описанная схема работы XPath может быть хорошо использована при отображении вершин иерархических баз данных в XML или HTML документ, в частности и для СУБД НИКА. XPath позволяет обращаться с элементами документа, которые являются узлами иерархической структуры. Таким образом XPath может быть использован при обходе иерархии вершин, отображенных в XML или HTML документ.
Построение отображения вершин базы данных НИКА в XML или HTML документ.
Возможны различные способы построения отображения вершин базы даных НИКА в гипертекстовый документ посредством шаблона XSL. Один способ состоит в том, чтобы сразу динамически создавать XML-документ, используя XSL-элемент list - список. Для форматирования элементов списка можно использовать HTML-элементы, задавая их как атрибуты к элементам списка el (см. ниже). Для отображения иерархии элементов можно использовать тот же самый элемент list с вложенными списками, т. е. в качестве элемента списка может быть использован элемент list. Элемент list позволяет отсортировать элементы списка в разном порядке. В случае табличного представления данных следует реализовать соответствующий элемент на языке XSL. О возможных видах представления данных в документе см. работу [8]. Пример элемента 'список' для показа вершин базы данных НИКА. Элемент написан посредством XSL-шаблона.
Описание XSL-шаблона list.
<list type="text|number|{user_defined_type}"
order="+|-"
kind="disc|decimal|none|delimiter"
delimiter={string-value}
first_delimiter={string-value}
last_delimiter={string-value} help="1">
(<rem>text string </rem>)
(<att>text label for attributes print </att>)
<el (type={html_tag} (value={html_attrs}))> element 1 </el>
<el (type={html_tag} (value={html_attrs}))> element 2 </el>
<el (type={html_tag} (value={html_attrs}))> element 3 </el>
. . .
</list>
list - список
type = { ["text"] | "number" | qname-but-not-ncname } - тип списка (для сортированного списка является обязательным параметром);
order = { ["+"] | "-" }- xsl:sort order={ "ascending" | "descending" }порядок сортировки - по возрастанию или по убыванию;
kind = { ["disc"] | "decimal" | "none" | "delimiter" }- просмотр списка, как ненумерованного, нумерованного, простого списка или списка с разделителями, определенными пользователем;
delimiter = { text-string }- разделитель элементов списка;
first_delimiter = { text-string }- разделитель перед первым элементом;
last_delimiter = { text-string }- разделитель после последнего элемента;
help = { "1" }- просмотр описания элемента list;
[...] - значение по умолчанию;
el - элемент списка
type = { html-tag-string }- a, img, h1 и т. д.
value = { html-element-attributes }- атрибуты html-элемента, перечисленные через точку с запятой: ATTR1=VALUE1;ATTR2=VALUE2;ATTR3=VALUE3;...;ATTRn=VALUEn
Элементы или атрибуты, указанные в круглых скобках могут быть пропущены.
Другой способ включает в себя первый. Динамически создается XML-документ, содержащий фрагмент иерархии базы данных НИКА. Имена вершин - это элементы XML. Содержимое элементов - это значения для терминальных вершин и подчиненные вершины для структурированных вершин. Для показа этой иерархии различными типами отображения необходимо применить к полученной иерархии соответствующие XSL-элементы. Так для показа в виде списка необходимо применить элемент list. Для применения XSL-элемента к соответствующей иерархии вершин необходимо организовать проход по этой иерархии посредством рекурсивного обращения:
<xsl:template name="db_vertices_hrh_pass">
<xsl:param name="vertices"/>
...
<!-- для каждой подчиненной вершины, задаваемой параметром vertices, относительно текущей вершины -->
<xsl:for-each select="$vertices">
...
<!-- рекурсивный вызов с параметром vertices="*": обработка всех подчиненных вершин -->
<xsl:call-template name="db_vertices_hrh_pass">
<xsl:with-param name="vertices" select="*"/>
</xsl:call-template>
...
</xsl:for-each>
...
</xsl:template>
Параметр vertices задает XPath выражение, соответствующее всем элементам, подчиненным текущему. Указанный параметр должен быть задан при первом обращении к элементу db_vertices_hrh_pass, т. к. в нем необходимо указать первую текущую (контекстную) вершину. Например, если верхним элементом иерархии элементов вершин является doc, содержащий все остальные элементы, то вызов должен выглядеть следующим образом:
<!-- обработать все вершины, подчиненные элементу doc -->
<xsl:call-template name="db_vertices_hrh_pass">
<xsl:with-param name="vertices" select="/doc/*"/>
</xsl:call-template>
Элемент list необходимо вызывать в процессе обработки; содержимое элементов вершин предсталяется с помощью элемента el.
Рассмотрим более простой пример отображения с использованием HTML-элемента <ul> - ненумерованный список. Тогда описанный выше XSL-элемент прохождения по иерархии элементов вершин базы данных НИКА будет выглядеть следующим образом (шаблон db_vertices_hrh_pass вызывается без параметра непосредственно из шаблона doc - верхний элемент иерархии отображенных вершин):
exmpl. xsl
<xsl:stylesheet xmlns:xsl="http://www. w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="doc"> <!-- верхний (корневой) элемент -->
<html>
<body>
<xsl:call-template name="db_vertices_hrh_pass"/> <!--вызов шаблона для прохождения по-->
</body> <!--иерархии элементов, содержащихся в doc,-->
</html> <!--вместо обычного вызова xsl:apply-templates-->
</xsl:template>
<xsl:template name="db_vertices_hrh_pass"> <!--шаблон для прохождения по иерархии-->
<ul> <!--элементов и печати в виде html-списка-->
<xsl:for-each select="*">
<xsl:variable name="vert_name" select="name(current())"/>
<xsl:variable name="vert_prn">
<xsl:choose>
<xsl:when test="starts-with($vert_name,'v-')">
<xsl:value-of select="substring-after($vert_name,'v-')"/>
</xsl:when>
<xsl:when test="starts-with($vert_name,'n-')">
<xsl:value-of select="substring-after($vert_name,'n-')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$vert_name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="current()/*"> <!-- структурированная вершина -->
<li><b><xsl:value-of select="$vert_prn"/></b></li> <!-- название вершины -->
<xsl:call-template name="db_vertices_hrh_pass"/> <!-- обработка подчиненных -->
</xsl:when>
<xsl:otherwise> <!-- терминальная вершина -->
<li>
<xsl:choose>
<xsl:when test="starts-with($vert_name,'v-')">
<xsl:choose>
<xsl:when test="$vert_prn='1'"> <!-- только значение -->
<xsl:value-of select="current()"/>
</xsl:when>
<xsl:when test="$vert_prn='2'"> <!-- изображение -->
<img>
<xsl:attribute name="src"><xsl:value-of select="current()"/></xsl:attribute>
</img>
</xsl:when>
<xsl:when test="$vert_prn='3'"> <!-- заголовок -->
<h3><xsl:value-of select="current()"/></h3>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:otherwise> <!-- название = значение -->
<xsl:value-of select="name(current())"/> = <xsl:value-of select="current()"/>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Для проверки этого шаблона можно рассмотреть xml-файл:
exmpl. xml
<?xml version="1.0" encoding="windows-1251"?> <!-- указание кодировки -->
<?xml-stylesheet href="exmpl. xsl" type="text/xsl"?> <!-- ссылка на xsl-шаблон -->
<doc> <!-- верхний элемент -->
<a1>
<a2> text 2 </a2>
<a3> text 3 </a3>
</a1>
<a4> text 4 </a4>
<a5>
<a6> text string 1 </a6>
<a7> text string 2 </a7>
<a8>
<a9> вершина 9 </a9>
<a10> вершина 10 </a10>
<a11> вершина 11 </a11>
<a12>
<a13> vertex text </a13>
<a14> vertex text string </a14>
</a12>
</a8>
</a5>
<a15> test vertex </a15>
</doc>
В результате на экране должно быть отображение элементов в виде вложенных html-списков:

Используя тот же самый xsl-шаблон в случае базы данных "Новомученики и исповедники Русской Православной Церкви XXв." можно получить следующий результат:

. . .
Исходным XML-файлом является следующий.
<?xml version="1.0" encoding="windows-1251"?> <!-- указание кодировки -->
<?xml-stylesheet href="m. xsl" type="text/xsl"?> <!-- ссылка на xsl-шаблон -->
<doc>
<v-3></v-3>
<ГодРождения>1872</ГодРождения>
<ДеньРождения>8</ДеньРождения>
<МесяцРождения>5</МесяцРождения>
<МестоРождения>Нижегородская губ., Ардатовский у., с. Павловское</МестоРождения>
<v-1>протоиерей</v-1>
<v-1>Сын священника и отец трех сыновей-академиков</v-1>
<Фотографии>
<n-1>
<v-2>oni-10.jpg</v-2>
<v-1>протоиерей Николай Боголюбов гг.</v-1>
</n-1>
</Фотографии>
<ПЕРИОДЫ_ЖИЗНИ>
<n-1>
<Период_жизни>гг.</Период_жизни>
<Образование>
<n-1>
<УчебЗаведение>Лысковское духовное училище</УчебЗаведение>
<ГодОкончания>1886</ГодОкончания>
</n-1>
. . .
</doc>
Исходным XSL-шаблоном служит тот же самый шаблон db_vertices_hrh_pass, помещенный в файл m. xsl.
Расширение возможностей языка HTML посредством XSL.
Рассмотрим множество реализаций XML на основе HTML. Пусть Sh - это множество элементов языка HTML и их атрибутов. Выделим из всего множества XSL-схем такие, минимальной реализацией которых является Sh: S={S1,...,Sn}: ShÍSi, "i=1,n. Для схем Si схема Sh является базовой схемой. Любое множество Si содержит элементы, порожденные этой XSL-схемой, и атрибуты этих элементов Si={A1i,...,Aji, Aj+1i,...,Aki}, где el(Si)={A1i,...,Aji}ÍSi - множество элементов, порожденных XSL-схемой Si и at(Si)={Aj+1i,...,Aki}ÌSi - множество атрибутов этих элементов. При этом на множестве Si задано отображение Fi: Ap -> Sa, "ApÎel(Si), SaÍat(Si) (Sa может быть пустым множеством Æ), которое ставит в соответствие каждому элементу из множества el(Si) некоторое подмножество атрибутов множества at(Si). Среди рассматриваемых схем существует подмножество схем S'ÌS, неизменяющих набор элементов HTML-схемы Sh, т. е. el(Sh)=el(Si'), "Si'ÎS'. Такие схемы изменяют только множество атрибутов at(Sh), т. е. at(Sh)Íat(Si'), "Si'ÎS'. Схемы S' имеют те же самые элементы, что и HTML-схема Sh и расширяют набор атрибутов HTML элементов. Такие схемы позволяют обеспечить полную совместимость с языком HTML, в случае когда программа не поддерживает язык XSL, и в тоже время позволяют сделать HTML расширяемым посредством новых атрибутов.
Для примера рассмотрим элемент list. Этот элемент можно реализовать посредством HTML-элемента ul - ненумерованный список, не изменяя названия исходного HTML-элемента ul. Стандартный элемент ul можно расширить дополнительными атрибутами, например атрибутом sort для сортировки элементов списка. Такой HTML-подобный XML-документ будет показан программами, которые поддерживают только HTML, но элементы списка ul не будут отсортированы. В случае, когда программа поддерживает XSL, элементы списка будут отсортированы в алфавитном порядке.
Заключение
Описанный выше подход с использованием элемента список list, созданный с помощью XSL-схемы, был реализован для СУБД НИКА. В отличии от HTML-сервера СУБД НИКА, описанного в [2], в данной реализации пользователь имеет возможность изменять вид отображения вершин базы данных посредством XSL-схемы, а не только посредством спецификаций, заданных в дереве описания даннных СУБД НИКА. Посредством XSL-схемы можно задать более точно способ отображения терминальных вершин с использованием возможностей изменения стиля, которые предоставляют XSL и CSS. Необходимо отметить, что стандартные программы просмотра XML и HTML не позволяют использовать объекты форматирования [9], определенные языком XSL, а только ранее определенные стили посредством CSS. Кроме того, при добавлении новых возможностей в XSL, XML и HTML XSL-схема позволяет использовать эти возможности без изменения программы HTML-сервера СУБД НИКА. Подход с использованием наиболее общего формата данных, в котором в качестве элементов используются названия вершин, требует дополнительных усилий при написании общей XSL-схемы. Следует отметить, что наиболее реальным является описанный подход, в котором в качестве минимальной реализации берется за основу XSL-схема языка HTML, которая при необходимости может быть расширена дополнительными атрибутами. Основным преимуществом такого подхода является полная совместимость с HTML и расширяемость этой реализации HTML посредством XSL.
Литература
1. H. Brown, Standards for structured documents, Computer journal, vol.32, no.6, 1989.
2. ,Тищенко построения web-сервера на основе объектно-ориентированной базы данных, Информационные технологии и вычислительные системы, N4, 1997, сс.90-99.
3. T. Berners-Lee, D. Connoly. Hypertext markup language (HTML), v.1.2, documentation, june 1993, http://www. w3c. org/markup/draft-ietf-iiir-html-01.txt.
4. A. N. Bogacheva, N. E. Emelyanov, A. P. Romanov. Object-oriented markup language and restructuring hierarchical database objects,
proceedings of the second international workshop on advances in databases and information systems, Moscow, june 27-30, 1995,
vol.1, pp. 79-81.
5. , , Романов информационных систем по формам входных и выходных документов,
PC magazine/russian edition, N1/1993, сс.85-89.
6. XSL transformations (XSLT), v.1.0. W3C recommendation 16 November 1999, http://www. w3c. org/tr/1999/rec-xslt.html.
7. P. Grosso, N. Walsh. XSL concepts and practical use, v.1.5, 2000, http://www. /docs/tutorials/xsl/xsl/frames. html.
8. Емельянов анализ документного интерфейса, М., препринт, ВНИИСИ, 1987, 52 стр.
9. С. Холзнер. XSLT, библиотека программиста, издат-во "Питер", 2002г., сс. 42, 59, 67.
10. , Н.Е. Емельянов, , В.А. Солдатов, СУБД НИКА // Системы управления базами данных и знаний, изд. "Финансы и статистика",Москва,1991,с.208-249.


