(Продолжение, начало см. МК № 48, 51—52 (167, 170—171))
Триединое целое
Искушенный читатель знает, что любая классификация и любое разграничение понятий условны. Можно с известной долей уверенности сказать, что книги по информационным технологиям делятся на две категории: «боекомплекты» для профессионалов и «заварочные пакеты» для «чайников». Я мог бы предложить и другую классификацию: книги хорошие, плохие и очень плохие (говорить об очень хороших книгах не приходится, так как сам жанр еще не сформировался окончательно, а классики столь редки). В категорию «боекомплектов» могут попасть как хорошие, так и очень плохие книги, в то время как произведения, от которых получаешь настоящее эстетическое наслаждение, могут быть заполнены целиком «заваркой». Ничего не поделаешь — классификация основательно влияет на восприятие того, что классифицируется. Что касается расширяемого языка стилей (eXtensible Style Language), то здесь процесс разделения на составляющие существенно упрощен самими создателями языка (см. ) — они предложили отдельные стандарты для следующих составных частей XSL:
язык выражений (expression language), используемый для обеспечения доступа к частям документа XML. Этот язык называется XML Path Language или, короче, Xpath;
язык для преобразования (трансформации) XML-документов—XSL Transformations (XSLT);
словарь XML для спецификации форматирования —XSL Formatting Objects (FO);
У тех энтузиастов, кто немного поработал с XSL (а среди интересующихся этим языком все в некотором роде новички, так как сам язык был частично стандартизирован всего два года назад), должны были заметить, что XPath и XSLT тесно переплетаются, и порой трудно понять, где заканчивается одно и начинается другое. Действительно, основатели языка предполагали, что XSLT будет использовать XPath для обращения к частям документа XML и их последующего преобразования и форматирования (в будущем — с помощью Formatting Objects). Поэтому конструкции XPath и XSLT очень часто встречаются вместе. Стандартизация и внедрение поддержки Formatting Objects в браузерах все еще находятся в стадии разработки, поэтому сейчас мы сосредоточимся на рассмотрении XPath и XSLT.
Не свернем с пути истинного
XPath («path» означает «путь») был задуман прежде всего для нахождения информации в XML-документе. При этом в процессе поиска активно используется логическая структура исходного документа. Используя XPath, в XML-документе можно отыскать структуры данных, удовлетворяющие определенным условиям, и применить к ним средства XSLT для преобразования или форматирования. Основные концепции XPath естественно вытекают из самого принципа иерархической организации данных в XML. Новое — это хорошо забытое старое, и в этом можно лишний раз убедиться, познакомившись с синтаксисом XPath, который очень напоминает иерархические структуры файловых систем UNIX и DOS. Думаю, что теперь пришло время пройтись по «путям» XPath.
Путь в XPath (location path) представляет собой последовательность из одного или нескольких шагов (location steps), разделенных значком «/». Как и в популярных операционных системах, пути бывают абсолютными (absolute location paths) и относительными (relative location paths). В последнем случае мы начинаем отсчитывать шаги от узла, называемого контекстным (context или context node), то есть от того, который сейчас, в данный момент рассматривается (понятие контекста напоминает понятие текущего каталога в операционных системах). На каждом шаге выбирается множество узлов, связанных с контекстным узлом с той или иной «степенью родства». Каждый шаг использует узлы, выбранные на предыдущем шаге, как контекст для дальнейшего поиска. Абсолютный путь начинается с символа «/» — это говорит о том, что шаги отсчитываются с корневого узла (root node).
Шаг в XPath, являющийся основной структурной единицей пути, обычно состоит из трех частей:
ось (axis), которая определяет тип отношения между контекстным узлом и теми узлами, которые выбираются на данном шаге;
тестовый узел (node test), который определяет тип и имя узлов, выбираемых на данном шаге;
предикаты (predicates), использующие разнообразные выражения, в том числе логические, для определения подмножества множества узлов, отобранных с помощью тестового узла
Шаг (location step) начинается с имени оси, далее дважды ставится двоеточие, после чего указывается имя тестового узла. Далее следуют выражения в квадратных скобках (наличие таких выражений необязательно). Пример:
child::product[position()=1]
В данном случае child — это имя оси, product — имя тестового узла, и [position()=1]
— предикат.
Подытожим сказанное о шагах в XPath. На каждом шаге в соответствии с осью и тестовым узлом отбирается некоторое множество узлов, которое потом фильтруется с помощью предикатов. Каждый узел этого множества является контекстным для последующих шагов. А сейчас, чтобы теоретические рассуждения на тему XPath не остались праздными разговорами, рассмотрим несколько конкретных выражений, приведенных в табл. 1.
Укоротим ось
Сразу видно, что предложенный синтаксис XPath обрекает нас на необходимость работы с довольно громоздкими выражениями, проигрывающими своим аналогам в UNIX и DOS в краткости и прозрачности. Создатели XPath
предусмотрительно изобрели сокращенную запись выражений языка, во многом напоминающую синтаксис путей в популярных операционных системах. В этой упрощенной записи ось child можно опустить, что очень удобно, так как эта ось встречается в выражениях XPath на каждом шагу. Например, вместо child::people/child::person можно просто писать people/person. Рассмотрим также некоторые другие примеры, приведенные в табл. 2.
Ближе к делу
Пришло время «пощупать» XPath своими руками, а если выражаться научным языком, то сейчас мы попробуем использовать некоторые типичные выражения XPath с целью визуализации структур XML. Напомню, что для наших целей необходимо установить parser 3.0 (файл msxml3.exe), если он у вас еще не инсталлирован. Несложная процедура установки кратко описана в статье «XSL — зеркало для XML».
Создайте файл с именем myXPathTest.xml и занесите в него следующий текст:
Это нужно выделить курсивом, а это нужно, кроме того, написать жирным шрифтом. Это снова — просто курсив. Это первый уровень. Это второй уровень. Это третий уровень.Это первый уровень. Это второй уровень. Это третий уровень.Это — дедушка. Это — папа. Это — первый ребенок John, а это — второй ребенок Ivan.
Создайте файл myXPathTest.xsl и наберите в нем следующее:
<p></p><i></i><b></b><b></b><b></b><b></b><i></i>
Что касается исходного документа XML, то здесь, думаю, все ясно. Давайте разберемся со стилевой таблицей XSL. Конструкция
<p></p>
позволяет применить форматирование в виде отдельных параграфов элементов para, para1 и para2. Символ «|» в данном случае обозначает операцию объединения множеств узлов. Конструкции
<i></i>
и
<b></b>
иллюстрируют форматирование вложенных элементов (в данном случае элементов emphasis) с использованием выражений XPath. Из данного примера видно, что жирным шрифтом оформляются только те элементы emphasis, которые вложены в элементы того же типа. «Внешний» элемент emphasis оформляется только курсивом, так как он не содержится в других элементах emphasis.
Следующие две конструкции
…
и
…
показывают различие в использовании выражений «/» и «//» в XPath. В первом случае находятся и форматируются только дочерние узлы note узла level1. Во втором случае аналогичное форматирование применяется ко всем потомкам note того же самого элемента level1.
Шаблон
…
служит для форматирования вторых дочерних узлов (с именем child) для всех потомков узла grandFather. В исходном документе XML имеется только один потомок элемента grandFather, который имеет дочерние узлы child, — следовательно, в данном случае будет отформатирован только один элемент.
Конструкция
…
используется для форматирования только тех узлов child, текстовое содержание которых представляет собой строку символов «John». Заметьте, что в данной конструкции эта строка символов заключена в одинарные кавычки, так как само значение атрибута match нужно указывать в кавычках.
А сейчас откройте файл myXPathTest.xml в окне Internet Explorer, и вы увидите результат «слияния» исходного файла XML со стилевой таблицей:
(Продолжение следует)
