Учебное пособие (1075724), страница 13
Текст из файла (страница 13)
2.25. Результат выполнения примера 2.14.Рассмотрим более подробно текст преобразования XSLT.<?xml version="1.0" encoding="Windows-1251"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><!-- Объявление ключей для группировки и поиска -->107<xsl:key name="CourseName" match="Data" use="CourseName"/>Ключ используется для группировки данных по курсам.<xsl:key name="Department" match="Data" use="Department"/>Ключ используется для группировки данных по кафедрам.<xsl:key name="Student" match="Data" use="concat(Department,Student)"/>Ключ используется для группировки данных по студентам внутри кафедры.<xsl:key name="Res" match="Data" use="concat(Department, Student,CourseName)"/>Ключ используется для получения оценки по кафедре, студенту и курсу.<xsl:template match="/"><!-- Правило обработки корневого элемента XML - документа --><HTML><BODY><TABLE BORDER="2"><TR><!-- Пустая ячейка соответствует первому столбцу --><TH/><!-- В столбцах отображаются названия предметов, по предметампроизводится группировка --><xsl:for-each select="//Data[generate-id(.)=generateid(key('CourseName',CourseName))]">XPath-выражение в атрибуте select выбирает список курсов с группировкой(с исключением дубликатов).Такой способ группировки в XSLT называется «методом Мюнха» (по имениавтора метода).
Более подробно этот метод описан в [Валиков, 2002].Функцияgenerate-id(элементдокумента)генерируетуникальныйидентификатор для элемента документа. В соответствии со стандартом, эта108функция является детерминированной, то есть для одного и того же элементадокумента (параметра функции) она всегда возвращает одинаковое значение.Если параметром функции generate-id является множество узлов, то онавозвращаетидентификатордляпервогоузла.Тоесть«generate-id(key('CourseName',CourseName)» вернет уникальный идентификатор первогоэлемента Data из тех, которые вернет функция key.Не важно, какой именно элемент Data будет стоять первым.
Важно то, чтоэто выражение для одного и того же параметра CourseName будет возвращатьодин и тот же уникальный идентификатор, который соответствует какому-тоэлементу Data из ключа. Фактически будет возвращаться идентификатор группы.Выражение «generate-id(.)» возвращает уникальный идентификатор длятекущего элемента.Выражение//Data[generate-id(.)=generate-id(key('CourseName',CourseName))]проверяет, что текущий элемент Data является первым элементом в группе.Параметр CourseName, который передается в функцию key, вложен в текущийэлемент « .
», фактически это « ./CourseName ». То есть левая и правая частьоператора равенства связаны по значению элемента CourseName.Таким образом, из всех элементов Data с одинаковым значением вложенногоэлемента CourseName возвращается только один, который соответствует первомуэлементу Data, возвращаемому функцией key. То есть реализуется группировка(исключение дубликатов) по элементу CourseName.В случае многоуровневой группировки в параметр ключа включаются всеуровни группировки путем конкатенации строк, например concat(Department,Student)В версии стандарта XSLT 2.0 этот метод можно не использовать, так какпредусмотрен специальный элемент xsl:for-each-group, который реализуетгруппировку.<xsl:sort select="CourseName" data-type="text"/>Список курсов сортируется по возрастанию.109<TH><xsl:value-of select="CourseName"/></TH>В ячейку заголовка столбца таблицы заносится название курса.</xsl:for-each></TR><xsl:for-each select="//Data[generate-id(.)=generateid(key('Department',Department))]">Группировка по кафедрам с использованием рассмотренного методагруппировки.<xsl:sort select="Department" data-type="text"/>Сортировка по названию кафедры.<!-- Данные о кафедре --><xsl:variable name="var1" select="Department"/>Создание переменной с названием кафедры<TR><TH><xsl:value-of select="$var1"/></TH>В ячейку заголовка строки таблицы заносится название кафедры.
В строки сназванием кафедр данные не выводятся.</TR><!-- Данные о студенте --><xsl:for-each select="//Data[generate-id(.)=generateid(key('Student',concat($var1, Student)))]">Группировка по именам студентов внутри кафедры.<xsl:sort select="Student" data-type="text"/><xsl:variable name="var2" select="Student"/><TR><TD><xsl:value-of select="$var2"/></TD>110<xsl:for-each select="//Data[generateid(.)=generate-id(key('CourseName',CourseName))]">Для каждого студента необходимо осуществить перебор всех предметов, таккак название предмета используется в ключе поиска.<xsl:sort select="CourseName" data-type="text"/><xsl:variable name="var3" select="CourseName"/><xsl:variable name="res" select="key('Res',concat($var1, $var2,$var3))"/>Получение по ключу Res элемента Data, который соответствует текущейкомбинации кафедры, студента и предмета.<TD><xsl:value-of select="$res/Result"/></TD>Вывод оценки Result из полученного по ключу Res элемента Data, которыйсоответствует текущей комбинации кафедры, студента и предмета.
Если такойэлемент не обнаружен, то xsl:value-of возвращает пустое значение.</xsl:for-each></TR></xsl:for-each></xsl:for-each></TABLE></BODY></HTML></xsl:template></xsl:stylesheet>2.2.15 Стандарт XSLT 2.0В этом разделе рассмотрены основы XSLT 1.0 [XSLT, 1999]. В январе 2007года появился стандарт XSLT 2.0 [XSLT, 2007].111Основным отличием второй версии является то, что в нем вместо XPath 1.0используется XPath 2.0.
Также важными дополнениями в этом стандарте являютсявозможность использования группировки и создания пользовательских функций.2.3 Материалы для дальнейшего изученияРекомендуется ознакомиться со стандартами XPath 1.0 [XPath, 1999] и XSLT1.0 [XSLT, 1999] (на русском языке).Основы технологии XSLT подробно рассмотрены в [Валиков, 2002].Также рекомендуется ознакомиться со стандартами XPath 2.0 [XPath, 2007] иXSLT 2.0 [XSLT, 2007].2.4 Контрольные вопросы1.
Для чего предназначен язык XPath?2. Какие основные выражения используются в XPath?3. Чем отличается обращение к элементам от обращения к атрибутам вXPath?4. Каким образом в XPath можно использовать фильтры и операторысравнения?5. Что такое оси выборки в XPath и как их использовать?6. Что такое контекстный XPath-запрос и чем он отличается отнеконтекстного? Почему контекстные XPath-запросы так широкоиспользуются?7.
Какие группы функций существуют в XPath?8. Как использовать арифметические действия в XPath?9. Как отобразить XML-файл с использованием таблиц стилей CSS? Вчем ограничения этого подхода?10.Для чего предназначена технология XSLT?11.Какие три варианта преобразований обычно выполняют с помощьюXSLT?12.Что такое XSLT-процессор?11213.КакиеэлементытехнологииXSLTпозволяютсоздаватьпреобразования, адаптирующиеся к структуре входного документа?14.Как реализуются циклы и сортировка в XSLT?15.Как реализуются условия в XSLT?16.Как реализуется включение стилей в XSLT?17.Для чего используются переменные в XSLT? В чем их основнаяособенность?18.Что такое расширения XSLT? Какие задачи можно решать с ихпомощью?19.Как реализуется ключи поиска в XSLT?20.Как можно реализовать группировку в XSLT?1133 Глава 3.
Описание структуры документов XML3.1 Использование DTD для описания структуры документовXMLDTD является одним из способов проверки правильности структурыдокумента XML. Исторически он появился даже ранее, чем технология XML, таккак DTD-описания перешли в XML из SGML.DTD расшифровывается как Document Type Definition, описание типовдокумента.В XML-документах DTD определяет набор используемых элементов,идентифицирует элементы, которые могут использоваться внутри другихэлементов, определяет возможные атрибуты для каждого элемента.Подробно DTD-описания рассматриваются в спецификации XML [XML,2000].3.1.1 Пример внешнего DTDРассмотрим пример использования DTD для документа XML.
В этомпримере используется внешний DTD, который располагается в отдельном файле.В XML-документ встраивается ссылка на этот внешний файл.Пример 3.1.Файл XML:<?xml version="1.0" encoding="Windows-1251"?><!DOCTYPE languages SYSTEM "languages.dtd" ><languages><language id="1"><name>HTML</name><year>01.01.1990</year><howold>19</howold></language><language id="2"><name>XML</name>114<year>01.01.1998</year><howold>11</howold></language><language id="3"><name>SGML</name><year>01.01.1986</year><howold>23</howold></language><empty attr1="1" attr2="текст"/><CDATA_Example><![CDATA[<<<<<<<<<<>>>>>>>>>]]></CDATA_Example></languages>Файл DTD:<?xml version="1.0" encoding="UTF-8"?><!-- В файле DTD могут быть использованы комментарии, если объявленаинструкция обработки xml --><!ELEMENT name (#PCDATA)><!ELEMENT year (#PCDATA)><!ELEMENT howold (#PCDATA)><!ELEMENT CDATA_Example (#PCDATA)><!ELEMENT language (name, year, howold)><!ATTLIST languageid CDATA #REQUIRED><!ELEMENT empty EMPTY><!ATTLIST emptyattr1 CDATA #REQUIREDattr2 CDATA #REQUIRED><!ELEMENT languages (language+, empty, CDATA_Example)>115ПроверитьсоответствиеXML-документафайлуDTDможносиспользованием XMLPad.Для этого необходимо открыть документ XML и выбрать пункт меню«XML/Validate».Если документ «валиден», то есть соответствует DTD, то выдаетсясообщение об отсутствии ошибок.Рис.
3.1. Результат выполнения примера 3.1.Присоединение DTD-файла к документу XML производится во второйстроке XML-документа:<!DOCTYPE languages SYSTEM "languages.dtd" >Имя файла, который содержит DTD – «languages.dtd». К файлу DTD можетбыть указан полный путь, если он расположен в другом каталоге.Рассмотрим более подробно текст DTD-описания.<?xml version="1.0" encoding="UTF-8"?><!-- В файле DTD могут быть использованы комментарии, если объявленаинструкция обработки xml -->116DTD-документ может быть объявлен как XML-документ, то есть начинатьсяс инструкции обработки <?xml . . . ?>.















