(Продолжение, начало см. в МК № 48, 5152, 3, 57 (167, 170171, 174, 176178))
XML-технологии: фильтры XSL
В последних статьях мы рассмотрели некоторые возможности XSL, которые позволяют автоматизировать оформление документов XML, имеющих регулярную структуру. Напомню, что при форматировании исходного документа в виде таблицы мы использовали специальный элемент <xsl:for-each> для организации последовательного перебора узлов, подлежащих трансформации. Мы научились выводить в окне браузера таблицу с отсортированными по определенному полю записями, а также применять условное форматирование (элемент <xsl:choose>) к ее ячейкам. В практических задачах часто возникает необходимость фильтровать содержимое базы данных, оставляя на экране лишь ту информацию, которая удовлетворяет определенному критерию отбора. Такая постановка задачи является классической для реляционных баз данных, а желаемый эффект достигается путем использования запросов к одной или нескольким связанным таблицам. Если вы никогда не имели дело с базами данных, но на вашем компьютере установлена какая-нибудь версия Microsoft Access, вы можете легко научиться конструировать и выполнять запросы к реляционным таблицам. Нас же сейчас будут интересовать исключительно средства XSL, предназначенные для выборочного показа информации, содержащейся в документе XML.
Создадим файл filter.xml и занесем в него следующий текст:
Приведенный выше документ XML имеет регулярную структуру, хотя его форма на первый взгляд существенно отличается от таблицы. Попробуем подать запрос к этому документу и вывести в табличной форме только те данные о книгах, которые удовлетворяют определенным условиям. Для этого построим в файле filter.xsl специальную стилевую таблицу:
Открыв файл filter.xml в окне Internet Explorer, вы увидите таблицу HTML, содержащую лишь одну запись. Принцип работы XSL в данном случае прост. В стилевой таблице мы использовали устаревшее пространство имен
Это чтобы обеспечить тем пользователям, у которых не установлена специальная программа-анализатор, возможность просматривать в окне Internet Explorer 5.0 результат слияния файла XML с документом XSL.
Ключевым элементом документа filter.xsl является тэг XSLT:
который обеспечивает прохождение в цикле тех элементов review исходного документа XML, для которых содержимое узла author равно ‘Pushkin’. Это слово заключено в одинарные кавычки, так как существуют внешние двойные кавычки, между которыми оно находится. С кавычками вообще следует обращаться осторожно. Следите за тем, чтобы ваши двойные кавычки выглядели точно так же, как и мои, иначе возможны проблемы с визуализацией документа. Обратите внимание, что значением параметра select является выражение XPath, позволяющее локализовать узлы, которые подлежат форматированию. В приведенном примере квадратные скобки заключают в себе выражение XPath, служащее для уточнения множества перебираемых в цикле узлов. Что касается выражений, то XPath позволяет строить достаточно сложные арифметико-логические конструкции, дающие возможность разработчику стилевых таблиц писать нетривиальные запросы к XML-документам. Читатели, знакомые с языком структурированных запросов SQL, несомненно, найдут некоторое сходство между средствами этого языка и XPath. Покажем основные операции, которые служат «строительными кирпичиками» для выражений XPath, используемых в запросах (см. табл.).
Знаки < и <= в документах XSL нельзя использовать непосредственно в тексте. Для вставки таких операций в документ знак < следует менять на стандартную сущность < (lt сокращение от «less than»; не забывайте ставить точку с запятой после этой аббревиатуры). Предположим, в нашем примере требуется вывести сведения о книгах, цена которых находится в промежутке от десяти до ста двадцати долларов. Тогда строку
нужно заменить на элемент
Наконец, построим запрос, выводящий сведения о книгах XIX и XXI века, цена которых больше $10. Для этого придайте атрибуту select элемента <xsl:for-each> значение
Внеся необходимые изменения в файл filter.xsl, сохраните его и откройте файл filter.xml в окне Internet Explorer. Получится картинка приблизительно такая, как показано на рисунке.
Мне осталось лишь отметить, что к этому же результату приводит и использование конструкции XSL со специальным элементом xsl:if. Чтобы посмотреть, как работает этот элемент, замените соответствующую часть документа filter.xsl фрагментом