Постраничный вывод с помощью xslt


Содержание

Xslt вывод

13.05.2010, 21:06

Как сделать принудительный вывод xslt преобразования в html?
Привет всем! пользуюсь Oxygen Editor процессор Xalan / Saxson Проблема простая — хочу.

XSLT 3.0
наконец-то появилась доступная для закачки .NET версия последней реализации XSLT 3.0 от Saxonic.

XSLT
Народ, каким образом можно написать XSLT шаблон, чтобы сымулировать команду include. Т. е.: Есть.

Sum XSLT
Есть xml файл, нужно сложить значения, пример.

XSLT рекурсия
Здравствуйте! Помогите пожалуйста с задачей. Нужно создать XSL файл для трансформации xml из: .

Постраничный вывод с помощью xslt

Для того, чтобы работать с данным документом, вам необходимо располагать как минимум браузером Internet Explorer версии 5.0 и выше. При этом будут работать некоторые из приведенных в тексте примеров.

Для того, чтобы у вас работали все примеры, необходимо установить XML-парсер версии 3. Если пример работает только под управлением XML-парсера версии 3, то в каждом случае это оговаривается особо. Отметим, что версии IE вплоть до 5.5 используют более ранние версии парсера, поэтому устанавливать его все равно придется. О более старших версиях IE узнайте самостоятельно.
Дистрибутив XML-парсера версии 3 можно найти по адресу http://msdn.microsoft.com/ XML/ XMLDownloads/ default.aspx.
После установки парсера вам нужно будет зарегистрировать его в реестре. Для этого в командной строке необходимо выполнить команду: regsvr32 msxml3.dll . Затем необходимо сообщить IE, что вы намерены использовать этот парсер. Для этого нужно запустить утилиту xmlinst . Утилиту xmlinst можно найти по адресу http://msdn.microsoft.com/ library/ default.asp?url=/ downloads/ list/ xmlgeneral.asp. Вы можете также попробовать найти ответы на вопросы об установке XML-парсера по адресу http://www.netcrucible.com/xslt/msxml-faq.htm.

А теперь перейдем к основной части нашего документа.

Введение

Рассмотрим простой пример XML-файла (ex01.xml).

tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >

Если мы откроем этот файл в браузере Internet Explorer, то мы увидим тот же самый текст, который приведен выше, вместе со всеми тегами и служебной информацией. Но нам не нужны теги и служебная информация! Мы хотим видеть только ту информацию, которая относится к делу, а при помощи тегов — управлять внешним видом этой информации. Эта задача решается легко и просто: необходимо к XML-файлу добавить шаблон преобразования — XSL-файл.

Перепишем наш XML-файл в следующем виде (ex01-1.xml).

tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >

И создадим XSL-файл ex01-1.xsl. Текст файла приведен ниже.

xsl:stylesheet version =» 1.0 » xmlns:xsl =» http://www.w3.org/TR/WD-xsl «>
xsl:template match =» / «>
p > strong > xsl:value-of select =» //title «/> strong > p >
p > xsl:value-of select =» //author «/> p >
xsl:template >
xsl:stylesheet >

Если мы теперь откроем файл ex01-1.xsl в браузере Internet Explorer, то мы увидим, что наша задача решена, — на экране осталась только необходимая нам информация, все теги исчезли. Результат, который вы получите на экране браузера, приведен ниже.

«Заметки об XSL»

Леонов Игорь Васильевич

Легко также увидеть, что порядок вывода строк у нас определяется только содержанием шаблона преобразования — XSL-файла. При необходимости шаблон можно легко поменять, абсолютно не меняя наш основной XML-файл.

Перепишем XML-файл. Информационную часть изменять не будем, а шаблон укажем другой ex01-2.xml.

tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >

Создадим XSL-файл ex01-2.xsl. Текст файла приведен ниже.

xsl:stylesheet version =» 1.0 » xmlns:xsl =» http://www.w3.org/TR/WD-xsl «>
xsl:template match =» / «>
p > strong > xsl:value-of select =» //author «/> strong > p >
p > xsl:value-of select =» //title «/> p >
xsl:template >
xsl:stylesheet >

Если мы теперь откроем файл ex01-2.xsl в браузере Internet Explorer, то результат будет другим.

Леонов Игорь Васильевич

«Заметки об XSL»

Отметим теперь момент, который является ключевым для разработчиков баз данных. Информация в XML-странице появляется, как правило, в результате запроса к базе данных. Запрос к базе данных в многопользовательской среде — это весьма дорогостоящая операция. Предположим теперь, что у нас нет XML и мы формируем стандартные статические HTML-страницы. В этом случае для решения задачи простого преобразования внешнего представления информации, например, для изменения сортировки, у нас есть два способа решения проблемы: выполнить запрос и сохранить результаты в каком-либо временном буфере на сервере или каждый раз при изменении внешнего представления выполнять новый запрос и формировать HTML-страницу заново.

Первый способ требует трудоемкого программирования, второй способ значительно увеличивает нагрузку на сервер базы данных, производительность которого часто является узким местом системы, — пользователю всегда хочется получать результаты быстрее.

XML и XSL — это исчерпывающее решение описанной выше проблемы. Фактически XML-страница — это и есть временный буфер для результатов запросов. Только вместо нестандартного и трудоемкого программирования мы теперь используем стандартный механизм XSL.

Есть и еще одно соображение, которое может быть существенным для разработчиков баз данных. Большинство современных СУБД могут форматировать результаты запроса к базе данных в виде XML-файла. То есть при построении интерфейса пользователя в рамках технологии XML и XSL мы добиваемся определенной независимости от поставщика СУБД. В части организации вывода — практически полной независимости. А эта часть весьма велика в большинстве прикладных систем, ориентированных на работу с базами данных. Конечно, помимо вывода есть еще ввод и серверная обработка бизнес-логики, но здесь вам придется искать какие-то иные решения.

Первые шаги

Разберем теперь более подробно первый пример. Напомним его текст.

tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >

Первая строка информирует браузер о том, что файл имеет формат XML. Атрибут version является обязательным. Атрибут encoding не является обязательным, но если у вас в тексте есть русские буквы, то необходимо вставить этот атрибут, в противном случае XML-файл просто не будет обрабатываться, — вы получите сообщение об ошибке.

Следующие строки — это тело XML-файла. Оно состоит из элементов, которые в совокупности образуют древовидную структуру. Элементы идентифицируются тегами и могут быть вложены друг в друга.

Элементы могут иметь атрибуты, значения которых тоже могут обрабатываться в соответствии с шаблоном.

На верхнем уровне XML-файла всегда находится один элемент. То есть файл вида

tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >
tutorial >
title > «Введение в CSP» title >
author > Леонов Игорь Васильевич author >
tutorial >

не будет обрабатываться браузером. Для преобразования в корректный XML-файл нужно добавить теги элемента верхнего уровня, например

knowledgeDatabase >
tutorial >
title > «Заметки об XSL» title >
author > Леонов Игорь Васильевич author >
tutorial >
tutorial >
title > «Введение в CSP» title >
author > Леонов Игорь Васильевич author >
tutorial >
/knowledgeDatabase >

Отметим, что имена тегов чувствительны к регистру символов. Подробнее об этом можно прочесть в любой книге по XML — элементам и атрибутам в этих книгах уделяется достаточно большое внимание.

Перейдем теперь к шаблону преобразования — к XSL-файлу. Задача XSL-файла — преобразовать дерево XML-файла в другое дерево, которое, например, будет соответствовать формату HTML и может быть изображено на экране браузера с учетом форматирования, выбора шрифтов и т.п.

Для того, чтобы браузер выполнил необходимое преобразование, нужно в XML-файле указать ссылку на XSL-файл

Рассмотрим теперь текст XSL-файла

xsl:stylesheet version =» 1.0 » xmlns:xsl =» http://www.w3.org/TR/WD-xsl «>
xsl:template match =» / «>
p > strong > xsl:value-of select =» //title» «/> strong > p >
p > xsl:value-of select =» //author «/> p >
xsl:template >
xsl:stylesheet >

Первая строка файла содержит тег элемента xsl:stylesheet . Атрибуты элемента — номер версии и ссылка на пространство имен. Эти атрибуты элемента xsl:stylesheet являются обязательными. В нашем случае пространство имен — это все имена элементов и их атрибутов, которые могут использоваться в XSL-файле. Для XSL-файлов ссылка на пространство имен является стандартной.

Заметим, что XSL-файл является одной из разновидностей XML-файлов. Он не содержит пользовательских данных, но формат его тот же самый. Файл содержит элемент верхнего уровня xsl:stylesheet , а далее идет дерево правил преобразования.

В настоящем документе мы не будем подробно пояснять, что означает каждый элемент XSL-файла. Мы будем приводить различные примеры и показывать результат в каждом примере. Читатель сможет самостоятельно сопоставить различные элементы XSL-файла и инициируемые этими элементами преобразования исходного XML-файла с пользовательской информацией.

В дальнейшем тексты XML- и XSL-файлов мы будем приводить в черно-белом варианте. Вы всегда сможете открыть реальный файл и посмотреть все в цвете. При необходимости закомментируйте ссылку на XSL-файл. Синтаксис комментария следующий — . В текст комментария нельзя вставлять символы — .

В первом примере мы посмотрели, как с помощью элемента xsl:value-of можно вывести в HTML-формате содержание элемента (текст, заключенный между тегами). Теперь мы посмотрим, как при помощи того же самого элемента можно вывести значение атрибута элемента.

Рассмотрим следующий XML-файл ex02-1.xml

В этом файле информация хранится не в содержании элементов, а в виде значений атрибутов. Файл ex02-1.xsl имеет вид

Обратите внимание на синтаксис ссылки на атрибут элемента — //dog/@name . Имя элемента и имя атрибута разделены парой символов » /@ «. В остальном синтаксис тот же самый, что и для ссылки на содержание элемента.

Результат имеет следующий вид:

Собака: Шарик. 18 кг, рыжий с черными подпалинами.

Обратим теперь внимание на следующий момент. В XSL-файле мы никак не использовали элемент tutorial . На самом деле можно было использовать полный путь. Перепишем наш XML-файл, увеличив глубину дерева (ex02-2.xml)

Файл ex02-2.xsl имеет вид

Результат будет тем же самым.

Собака: Шарик. 18 кг, рыжий с черными подпалинами.

В этом примере мы использовали полную ссылку для значений атрибутов. При выводе одиночных значений оба варианта — полная и сокращенная ссылка — работают одинаково.

На этом мы закончим разбор примеров с выводом одиночных значений и перейдем к выводу табличной информации — к выводу результатов запроса.

Вывод результатов запроса

До тех пор, пока мы работаем с несколькими реквизитами одного и того же объекта, разницы между XML и HTML практически нет. Однако стоит нам перейти к информации, содержащей несколько строк, как выгоды XML становятся очевидны. Но прежде чем перейти к выгодам, научимся выводить на экран простую таблицу.

Рассмотрим следующий XML-файл — ex03.xml. Текст его приведен ниже.

Предположим, что это результат запроса к базе данных и выведем на экран соответствующую таблицу.

Простая таблица

Первый шаг — это, как всегда, добавление шаблона преобразования. Модифицируем наш файл, добавив в него ссылку на шаблон. В результате получим файл ex03-1.xml.

В этот файл добавлен шаблон преобразования ex03-1.xsl.

Рассмотрим этот шаблон подробнее. Вот его текст.

Кличка Вес Цвет

Первая строка — новая для вас в XSL-файле (но не в XML-файлах!). Она говорит о том, что в XSL-файле нужно нормально воспринимать русские буквы. Без этой строки браузер не сможет корректно обработать русский текст в XSL-файле. Следующие две строки шаблона являются уже привычными. Следующие шесть строк — это строка, содержащая заголовки столбцов таблицы. Конструкция для извлечения текста заголовков таблицы вам уже знакома. А вот десятая строка тоже является новой:

Этот элемент шаблона позволяет выбрать и просмотреть все группы информации, полный путь к которым задается списком тегов «tutorial/enimals/dogs/dog» . Обратите внимание — путь задается полностью, ни один из тегов опустить нельзя. Далее в ячейки таблицы помещается информация о наших собаках. В отличие от первых примеров путь к соответствующей информации тоже задается полностью. Попробуем, например, разместить информацию о кличке чуть-чуть иначе ex03-2.xml:

Если мы в соответствующем XSL-файле поставим ссылку , то в соответствующем столбце никакой клички мы не увидим. Ссылка должна быть полной — . Вы можете самостоятельно поэкспериментировать с файлом ex03-2.xsl. Правильный результат приведен ниже.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Тузик 10 кг белый с черными пятнами
Бобик 2 кг бело-серый
Трезор 25 кг черный

Сортировка

В предыдущих примерах порядок строк в таблице полностью соответствовал группам тегов в XML-файле. Этот порядок можно изменять. Добавим в тег

Кличка Вес Цвет
Бобик 2 кг бело-серый
Трезор 25 кг черный
Тузик 10 кг белый с черными пятнами
Шарик 18 кг рыжий с черными подпалинами

Более интересные результаты мы получим, если попытаемся отсортировать таблицу по столбцу «Вес». Вначале попробуем сделать по аналогии с предыдущим примером — атрибут order-by=»dogName» заменим на order-by=»dogWeight» . Результат приведен ниже (ex03-4.xml, ex03-4.xsl).

Кличка Вес Цвет
Тузик 10 кг белый с черными пятнами
Шарик 18 кг рыжий с черными подпалинами
Бобик 2 кг бело-серый
Трезор 25 кг черный

Таблица действительно отсортирована по столбцу «вес», но это не числовая, а строковая сортировка! Для того, чтобы браузер воспринял значения как числа, ему необходимо об этом сказать, — вместо order-by=»dogWeight» необходимо написать order-by=»number(dogWeight)» . Теперь мы получили правильный результат (ex03-5.xml, ex03-5.xsl).

Кличка Вес Цвет
Бобик 2 кг бело-серый
Тузик 10 кг белый с черными пятнами
Шарик 18 кг рыжий с черными подпалинами
Трезор 25 кг черный

Приведем теперь пример сортировки по нескольким столбцам. Различные элементы в атрибуте order-by должны разделяться символом » ; » — order-by=»number(dogWeight); dogName» (ex03-6.xml, ex03-6.xsl). Таблица приведена ниже.

Кличка Вес Цвет
Трезор 10 кг черный
Тузик 10 кг белый с черными пятнами
Бобик 18 кг бело-серый
Шарик 18 кг рыжий с черными подпалинами

Следующий пример работает только под управлением XML-парсера версии 3. В нем строки сортируются по одному столбцу — по кличке собаки. Этот пример уже приводился выше, однако теперь мы используем новый синтаксис (ex03-7.xml, ex03-7.xsl).

При использовании нового синтаксиса используется ссылка на другое пространство имен

Это очень важный момент, и его никогда нельзя упускать из виду.

Кроме того, мы убрали атрибут order-by в элементе xsl:for-each и добавили другой элемент

Если элемент xsl: sort присутствует в элементе xsl:for-each , то он всегда должен стоять сразу после элемента xsl:for-each . Синтаксис элемента xsl:sort достаточно очевиден. В нем используются два атрибута: атрибут order — способ сортировки (по возрастанию или по убыванию) и атрибут select — имя поля, по которому производится сортировка. Если нам нужно отсортировать по первому элементу, как в данном примере, то вместо » dogName » можно было поставить точку — » . «, для других элементов нужно указывать его имя, например » dogColor «, если нам нужно отсортировать записи по цвету собаки. На самом деле атрибутов может быть пять — select , lang , data-type , order и case-order , но мы не будем здесь рассматривать все эти атрибуты, поскольку здесь мы не преследуем цель дать полное описание всех элементов, используемых в XSL, и их атрибутов.

Таблица результатов приведена ниже.

Кличка Вес Цвет
Бобик 2 кг бело-серый
Трезор 25 кг черный
Тузик 10 кг белый с черными пятнами
Шарик 18 кг рыжий с черными подпалинами

С использованием нового синтаксиса легко сменить сортировку по возрастанию на сортировку по убыванию (ex03-8.xml, ex03-8.xsl). Этот пример работает только под управлением XML-парсера версии 3.

Разница заключается в одной строке

Мы изменили значение атрибут order — значение ascending заменено на descending .

Таблица результатов приведена ниже.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Тузик 10 кг белый с черными пятнами
Трезор 25 кг черный
Бобик 2 кг бело-серый

Покажем теперь сортировку по нескольким полям (ex03-9.xml, ex03-9.xsl). Этот пример работает только под управлением XML-парсера версии 3.

В этом примере у нас фигурируют две строки с элементом xsl:sort .

Строки вначале сортируются по весу собаки, а затем по их кличкам в алфавитном порядке. Обратите внимание — для того, чтобы сортировка выполнялась в числовой последовательности, в элемент xsl:sort мы добавили атрибут data-type . Таблица результатов приведена ниже.

Кличка Вес Цвет
Волчонок 3 кг темно-серый
Трезор 10 кг черный
Тузик 10 кг белый с черными пятнами
Бобик 18 кг бело-серый
Шарик 18 кг рыжий с черными подпалинами

Заменив значение атрибута order by на descending , мы легко сгруппируем записи о собаках с одинаковым весом так, что клички будут идти в обратном алфавитном порядке. Соответствующий пример вы легко построите сами.

Кличка Вес Цвет
Волчонок 3 кг темно-серый
Тузик 10 кг белый с черными пятнами
Трезор 10 кг черный
Шарик 18 кг рыжий с черными подпалинами
Бобик 18 кг бело-серый

Элемент XSL:IF — фильтр

Рассмотрим теперь способы фильтрации строк таблицы. Первый пример использует старый синтаксис. В нем условие фильтрации указывается непосредственно в атрибуте select (ex04-1.xml, ex04-1.xsl).

Ниже приведена строка, в которую мы внесли необходимые изменения.

xsl:for-each select=»tutorial/enimals/dogs/dog [dogWeight$gt$10] » order-by=»number(dogWeight); dogName;»>

И таблица результатов.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Трезор 25 кг черный

Вы видите, что в таблице остались только те собаки, чей вес превышает 10 кг, причем первым стоит Шарик, чей вес меньше.

Все дальнейшие примеры в этом параграфе работают только под управлением XML-парсера версии 3.

Более гибкие возможности нам предоставляет новый синтаксис (ex04-2.xml, ex04-2.xsl). Обратите внимание — в новом синтаксисе атрибут order-by в элементе xsl:for-each не поддерживается, вместо него мы вставили два элемента xsl:sort .

Кроме того, условие фильтра у нас вынесено в отдельный элемент xsl:if .

Не забывайте указывать конечный тег элемента xsl:if .

В этом примере таблица результатов полностью аналогична предыдущей.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Трезор 25 кг черный

Полностью преимущества нового синтаксиса проявляются при использовании функций.

Рассмотрим следующий пример (ex04-3.xml, ex04-3.xsl). В этом примере используется функция position() , определяющая порядковый номер фрагмента в исходном XML-файле.

Соответствующий элемент xsl:if .

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Тузик 10 кг белый с черными пятнами

Продемонстрируем теперь использование более интересных функций — start-with(string,startSubstring) и contains(string,anySubstring) . Функция start-with(string,startSubstring) проверяет, начинается ли строка string с подстроки startSubstring . Пример — ex04-4.xml, ex04-4.xsl).

Синтаксис элемента xsl:if .

В этом элементе мы использовали переменные. Значения переменных были инициализированы ранее

Переменная varStartWith представляет собой подстроку, с которой должны начинаться требуемые нам клички. Она не меняется, поэтому инициализируется перед циклом. Переменная varDogName содержит кличку собаки, она меняется на каждом шаге цикла и, соответственно, инициализируется в теле цикла.

Кличка Вес Цвет
Тузик 10 кг белый с черными пятнами
Трезор 25 кг черный

Функция contains(string,anySubstring) проверяет, содержит ли строка string подстроку anySubstring . Пример — ex04-5.xml, ex04-5.xsl.

Синтаксис элемента xsl:if .

Этот пример полностью аналогичен предыдущему.

Кличка Вес Цвет
Бобик 2 кг бело-серый
Трезор 25 кг черный

Два элемента xsl:if , вложенные друг в друга, дают нам эффект оператора AND (ex04-6.xml, ex04-6.xsl).

Соответствующий фрагмент XSL-файла.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами

Можно добиться и эффекта оператора OR. Для этого нам нужно включить два цикла, в каждом из которых формируется своя выборка (ex04-7.xml, ex04-7.xsl).

Соответствующий фрагмент XSL-файла.

Кличка Вес Цвет
Бобик 2 кг бело-серый
Шарик 18 кг рыжий с черными подпалинами
Трезор 25 кг черный

Если сортировка не требуется, то можно вставить два элемента xsl:if в один элемент xsl:for-each .

Элемент XSL:IF — улучшение внешнего вида таблиц

Элемент xsl:if можно применять не только для фильтрации строк выборки. Очевидно, что он может быть полезен и во многих других областях. В этом параграфе мы разберем пример использования элемента xsl:if для улучшения внешнего вида таблицы. Заодно мы продемонстрируем реальное использование функции position() . Мы будем использовать эту функцию для того, чтобы чередовать цвет четных и нечетных строк таблицы (ex04-8.xml, ex04-8.xsl).

Фрагмент XSL-файла, который отвечает за требуемое чередование.

position() mod 2 = 0 «>
#CCCCCC

С элементом xsl:if и с функцией position() мы уже знакомы. Оператор mod дает нам остаток от деления на 2. А элемент xsl:attribute позволяет нам динамически подставлять в файл результатов различные атрибуты. Это очень мощный элемент, мы разберем еще одно применение этого элемента в следующем параграфе. А сейчас приведем для полноты картины таблицу результатов.

Кличка Вес Цвет
Шарик 18 кг рыжий с черными подпалинами
Тузик 10 кг белый с черными пятнами
Бобик 2 кг бело-серый
Трезор 25 кг черный

Динамическое формирование атрибутов на примере параметров ссылки в теге

Предположим теперь, что в каждой строке таблицы нам нужно сделать ссылку на некоторую страницу и передать на эту страницу два параметра — кличку и вес собаки. Понятно, что для каждой строки эти параметры — свои, и их нельзя прописать явно в XSL-файл. Тем не менее задача легко решается при помощи элемента xsl:attribute .

Мы не будем здесь строить специальный пример, ограничимся только соответствующим фрагментом XSL-файла.

И, наконец, мы ознакомились с комментариями в XSL-файлах. Это вторая строка приведенного фрагмента.

На этом мы завершим рассмотрение возможностей чистого XSLT и перейдем к последнему параграфу в этом документе — к динамическому изменению содержимого Web-страницы при помощи возможностей JavaScript и XML/XSLT без каких-либо дополнительных обращений к базе данных.

JavaScript и XML

Объединим теперь наши знания XML с возможностями, которые нам предоставляет JavaScript. Предположим, что нам нужно иметь возможность динамически изменять сортировку столбцов таблицы при щелчке на заголовке того или иного столбца. Понятно, что для этого нам нужно иметь один XML-файл, содержащий строки таблицы, несколько XSL-файлов, каждый из которых содержит требуемую сортировку и нечто, что объединит это все вместе и заставит работать.

Перейдем к реализации этой программы.

В качестве XML-файла возьмем привычный нам файл со списком собак — ex05-1.xml. Обратите внимание — мы убрали из файла ссылку на XSL-файл — нам нужно менять шаблон преобразования динамически.

Создадим также три XSL-файла, в каждом из которых у нас будет свой элемент xsl:sort , задающий сортировку строк — ex05-1a.xsl, ex05-1b.xsl, ex05-1c.xsl.

Приведем здесь текст элемента xsl:sort для каждого файла

Теперь нам осталось только объединить все это вместе. Ниже мы полностью приводим текст файла ex05-1.htm, сопроводив его необходимыми комментариями.

При загрузке страницы создадим все необходимые объекты и выведем первоначальный вариант на экран.

Постраничный вывод данных на PHP и MySQL

Автор статьи: Сергей Каминский

Сейчас многие сайты используют для хранения информации базы данных, в которых количество записей часто достигает сотен и тысяч. Поэтому, для удобства пользователей, записи выводятся порциями, то-есть постранично. В этой статье я расскажу как реализовать это на своем сайте с помощью PHP и MySQL. В приведенном примере будут выводиться ссылки «вперед» и «назад», «на первую страницу» и «на последнюю страницу», а также мы сможем ограничить количество ссылок, которые будут выводиться одновременно.

Как работает постраничный вывод информации

Для начала я обьясню принцип работы постраничного вывода, а потом мы рассмотрим готовый пример. Так как на одной странице должно быть определенное количество записей, то мы ограничим его в запросе к базе данных с помощью параметра LIMIT, а параметр OFFSET будет указывать с какой записи начинать вывод. Например ограничим количество записей по две на каждой странице и начнем вывод с первой страницы (то-есть с нулевой записи).

Для вывода второй страницы нам нужно увеличить значение параметра OFFSET на количество записей, то-есть на два.

Поскольку значение параметра OFFSET постоянно меняется, то мы количество записей присвоим переменной $quantity, а номер с которого нужно начинать вывод мы будем определять, умножая номер страницы на количество записей, и присваивать переменной $list, а потом подставим все это в запрос.

Для того, чтобы вывести навигацию для перемещения по страницам нам нужно узнать общее количество записей в базе MySQL и поделить результат на количество страниц, округлив полученное число в большую сторону. Давайте от теории перейдем к практике.

Готовый пример с комментариями

Первым делом создадим файл config.inc.php, который будет соединяться с базой данных MySQL. Мы будем подключать его во все скрипты, в которых нужно делать запросы к БД.

Чтобы было на чем испытать скрипт постраничного вывода, мы создадим с помощью install.php таблицу в базе данных MySQL и добавим туда семь записей.

Запустите install.php чтобы записи добавились в базу данных. Теперь приступим к написанию основного PHP-скрипта postranichno.php, который и будет осуществлять постраничный вывод из базы данных MySQL. Все действия описываются в комментариях для лучшего понимания того, что мы делаем.

Как убрать ненужные вам функции

Я в коде выделил два блока. Первый из них реализует вывод ссылок «назад» и «на первую страницу». Второй, соответственно, «вперед» и «на последнюю страницу». Если подобные возможности вам не нужны, то просто удалите данные блоки кода. Также в примере ограничено количестов ссылок которые выводятся до и после текущей страницы, чтобы не заполнять ими все окно браузера. Если вам это не нужно, то поменяйте значение переменной $limit на число, которое больше количества страниц, например, 3000.

Несколько советов

Для того, чтобы номера ссылок соответствовали номерам страниц и отсчет начинался не с нуля, а с единицы, мне пришлось немного усложнить код. Надеюсь, что комментарии помогли вам во всем разобраться. Вы можете изменять количество записей одновременно выводимых на странице на нужное вам целое число – на работу скрипта это никак не повлияет. Точно также вы можете просто поменять название файла postranichno.php на другое не изменяя код.

Размещая на своем сайте ссылку на первую страницу ставьте ее сразу на postranichno.php?page=1, а не просто на postranichno.php. Оба варианта дадут одинаковый результат, но первый будет более правильным выбором.

Если вы уберете все комментарии, то заметите, что здесь не так уж много кода и все намного легче, чем кажется на первый взгляд.

Другие записи по теме в разделе статьи по PHP и MySQL

XSLT первый шаг

1. Введение

Не прошло и трёх лет с тех пор, как у меня зародилась мысль о том, что пора изучать XSLT -))). Мысль зародилась, а везде ещё стоял PHP 4 и зверствовал Salbotron , который, мягко говоря, не отличался высокой производительностью. Да и редко какой браузер мог похвастаться поддержкой этого самого XSLT. По этим соображениям изучение столь перспективного направления я отложил до лучших времён. На данный момент можно смело заявить, что эти времена настали, поскольку вышел PHP 5 с поддержкой XSLT и сносной объектной моделью, а все топовые браузеры уже сами уверенно держат преобразования, только подавай XML. :)

Важные ссылки по теме, первоисточники:

  • http://w3c.org — комитет по разработке и продвижению стандартов всемирной паутины Internet. На данный момент он является первоисточником практически всех веб-ориентированных стандартов и рекомендаций.
  • http://www.w3.org/TR/xml — спецификация расширяемого языка разметки XML, который является основой современного веба. На момент написания статьи доступна пятая редакция версии 1.0, а также вторая редакция версии 1.1.
  • http://www.w3.org/TR/xml-names — спецификация использования пространств имён в XML.
  • http://www.w3.org/TR/xpath — спецификация по использованию языка поиска частей XML-документа XPath.
  • http://www.w3.org/TR/xsl/ — спецификация расширенного языка стилей XSL.
  • http://www.w3.org/TR/xslt — спецификация языка преобразований XSLT.
  • http://validator.w3.org/ — валидатор HTML.
  • http://www.w3.org/TR/xhtml1/ — спецификация XHTML1.0.

Переводы на русский язык:

Для лучшего понимания всего происходящего я рекомендую читать спецификации в следующем порядке:

  1. XML (это основа!)
  2. пространства имён (механизм разнородного XML-кода в одном файле)
  3. XPath (язык выборки элементов из дерева структуры)
  4. XSLT (преобразования)
  5. XHTML (то, к чему нужно стремиться)

Особо пытливые могут также уделить внимание расширенному языку стилей XSL.

2. Валидный XHTML

Что такое валидный XHTML? В первую очередь, это XML-документ, который должен соответствовать спецификации XML. Во-вторую, почти обычная HTML-страница, к которой все привыкли.

Почему нужен именно XHTML? Исключительно из соображений совместимости и кросс-браузерности. Страница в XHTML будет с большей вероятностью отображаться корректно в популярных браузерах, чем обычный HTML.

Для рядового клепателя страниц словосочетание XML-документ должно означать следующее:

  1. Документ содержит объявление XML-документа в самом начале страницы:
  2. Документ содержит один корневой элемент, в котором находятся все остальные.
  3. Все элементы (тэги) должны иметь закрывающую часть (
    ,

).


  • Атрибуты всегда имеют значение, которое обязательно указывается в кавычках (одинарных или двойных). Например, «radio» disabled= «disabled» /> .
  • Управляющие символы & , и > всегда должны маскироваться. Например, «?a=1&b=2» > & . Исключение составляет только , внутри которого спецсимволы можно не маскировать.
  • Также сам XHTML обязывает выполнять следующие условия:

    1. Документ должен объявлять пространство имён, в рамках которого будут использоваться элементы HTML.
    2. Документ должен объявлять DOCTYPE перед корневым элементом и указывать в нём один из типов XHTML и соответствующий DTD.

    Пример простого документа XHTML1.0:

    И так обо всём по порядку.

    Объявление XML-документа, в котором указывается его версия и кодировка.

    Для большей безопасности кодировку нужно всегда выставлять, иначе могут возникнуть проблемы с невалидными (по отношению к дефолтной кодировке) символами.

    Объявление типа документа и его схемы.

    Для XHTML 1.0 есть три типа — Strict (строгое соответствие рекомендациям W3C), Transitional (переходный тип) и Frameset (использование фреймов). Для каждого из них предусмотрен отдельный DTD.

    Объявление пространства имён и используемого языка.

    Очень важно указывать ссылку именно в таком регистре и никак иначе. Это связано с тем, что в XML имена элементов и содержимое их атрибутов регистрозависимы.

    Три версии XHTML1.0 предназначены для лучшей обратной совместимости:

    • Strict — обеспечивает наибольшее соответствие рекомендациям W3C со стороны браузеров. Однако и сам HTML-код должен следовать этим рекомендациям.
    • Transitional — менее строгое соответствие, которое заставляет браузер вести себя так, как если бы это был обычный HTML-документ.
    • Frameset — позволяет использовать фреймы.

    Помимо XHTML1.0 на данный момент доступен XHTML1.1:

    XHTML1.1 по сути является тем же XHTML1.0 Strict и призван вытеснить другие версии XHTML1.0. Однако, по сравнению с XHTML1.0 Strict, у него есть ряд отличий:

    1. Удалён атрибут lang , его роль выполняет xml:lang . (Модуль [ XHTMLMOD ])
    2. Для элементов a и map вместо атрибута name нужно использовать атрибут id . (Модуль [ XHTMLMOD ])
    3. Доступен набор элементов ruby . (Модуль [ RUBY ])

    Итак, если вам нужна наибольшая кросс-браузерность и совместимость с рекомендациями W3C, то XHTML1.1 самое оно!

    Из этих соображений результатом моих преобразований будет именно XHTML1.1.

    3. XSLT-преобразования

    Что такое XSLT? Это язык преобразований XML-документа, который был разработан как часть расширенного языка стилей (XSL).

    Зачем нужен XSLT? Он позволяет реализовать схему, при которой данные хранятся отдельно, а их представление отдельно. То есть, один XML-документ преобразуется с помощью другого XML-документа (XSL, в котором находятся XSLT-шаблоны) в конечный документ. Результатом может быть XML, HTML или текстовый документ любого формата.

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

    Валидным XSL-документом является XML-документ, у которого задано пространство имён xsl и присутствует корневой элемент stylesheet. В самом простом случае стиль может выглядеть, например, так:

    Этот стиль не содержит каких-либо явных определений шаблонов или других элементов XSL. Однако, его уже можно использовать. Чтобы посмотреть результат, достаточно сформировать произвольный XML-документ и подключить к нему этот стиль:

    За подключение стиля отвечает строка:

    Если файлы text.xml и test.xsl созданы и находятся в одной папке, то с помощью любого XSLT-парсера можно преобразовать исходный test.xml в результирующий документ. В качестве парсера могут выступать все популярные браузеры (IE5+, FF2+, Opera9+ и другие), а также модули в языках программирования, например, в PHP. Если вы используете браузер, то достаточно открыть test.xml, и он сразу отобразит примерно такой результат:

    При этом кодировка результата будет UTF-8, несмотря на то, что исходный документ был сформирован в windows-1251. К сожалению, браузеры обычно не позволяют просмотреть код результирующего документа, но модуль XSLT в PHP5 даёт возможность передать результирующий код в переменную, которую можно сохранить в файл. Поэтому, используя PHP, я приведу исходный код результирующего документа:

    Этот код не является валидным XML-документом и тем более XHTML1.1. Для того, чтобы сформировать нужный код, я усложню исходный XSL-стиль и добавлю туда необходимые шаблоны и преобразования. При этом исходный XML-документ останется без изменений.

    В качестве примера я приведу XSL-стиль, который при помощи XSLT будет выводить список атрибутов исходного XML-документа с их значениями, при этом будет формироваться валидный XHTML1.1. Итак, стиль:

    Чтобы понять, как он работает, я распишу каждое действие отдельно:

    Документ сформирован в кодировке windows-1251, о чём сообщается в атрибуте encoding. Версию XML-документа желательно всегда указывать, это рекомендация W3C.

    Затем идёт объявление корневого элемента, стиля:

    Обязательным атрибутом является определение пространства имён xsl через атрибут xmlns:xsl= «http://www.w3.org/1999/XSL/Transform» .

    Следующим шагом в корневом элементе stylesheet объявляется, каким образом нужно формировать результирующий документ:

    • method= «xml» — метод вывода документа. Результирующий документ будет в формате XML.
    • encoding= «windows-1251» — кодировка результирующего документа.
    • omit-xml-declaration= «no» — пропускать или нет начальное объявление XML-документа ( ). Может иметь значение «yes» или «no» (актуально только для html).
    • indent= «yes» — формировать отступы согласно уровню вложенности. Может иметь значение «yes» или «no».
    • media-type= «text/xml» — MIME-тип результирующего документа (используется только для метода вывода html).
    • doctype-public= «-//W3C//DTD XHTML 1.1//EN» — тип результируюшего документа (DOCTYPE)
    • doctype-system= «http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd» — ссылка на DTD

    Если метод вывода объявлен html, то значения атрибутов encoding и media-type будут подставлены в заголовок страницы ( . ) посредством метатега.

    Объявление основного шаблона:

    Именно этот XSLT-шаблон соответствует корню исходного дерева и будет вызван первым для преобразования. Атрибут match принимает значения, которые должны соответствовать языку поиска элементов XPath.

    Остальные шаблоны, если таковые имеются, должны подключаться из этого шаблона при помощи средств XSLT.

    Формирование XHTML-страницы. Оно начинается с элемента , у которого указано пространство имён xhtml:

    Атрибут xmlns= «http://www.w3.org/1999/xhtml» указывает на пространство имён xhtml, которое будет применено по умолчанию к этому элементу и всем дочерним элементам, у которых оно не задано явно.

    Атрибут xml:lang= «ru» указывает на язык, в котором сформирована страница (будущая).

    Эта часть стиля была нужна для формирования атрибутики валидного XHTML1.1 кода.

    Теперь что касается XSLT-преобразований:

    Вставка простого текста:

    Текст «Мой список:» будет подставлен в тег

    Организация цикла по выборке:

    Атрибут select принимает выражение XPath, на основе которого делает выборку. Если выборка вернула список узлов, то начинает работать цикл по каждому элементу.

    В данном случае выборка вернёт список атрибутов для этого (корневого) и всех дочерних элементов.

    В данном случае проверяется на чётность позиция элемента в списке выборки. Если тест возвращает true (порядковый номер элемента чётный), то срабатывает содержимое этого элемента.

    Управление атрибутами вышестоящего элемента:

    В данном случае, если позиция элемента чётная (определяется вышестоящим if), то в стиль элемента
    будет прописан серый цвет фона.

    Вывод значений элемента:

    Этот код подставит в вышестоящий элемент строку, собранную из имени текущего элемента и его значения. Содержимое атрибута select соответствует XPath.

    Вывод ссылки на разработчика парсера XSLT:

    Этот небольшой код XSLT формирует ссылку на разработчика парсера XSLT. Во многих случаях она будет разная и содержать разные значения.

    Результатом обработки этого стиля ( test.xsl ) станет такой код:

    Этот код соответствует стандарту XHTML1.1 и был сформирован на основе исходного XML-документа. Для проверки можно воспользоваться валидатором от W3C, который расположен по адресу http://validator.w3.org/.

    В браузере этот код выглядит примерно так:

    IE 6 FireFox 3 Opera 9.02

    4. Приложение

    Ссылки на исходный код

    Постоянный адрес статьи //anton-pribora.ru/articles/xml/xslt-first-step/. /Автор: Прибора Антон Николаевич, 2009 год/

    Использование PHP5 для обработки XSLT

    Для получения результирующего документа при помощи PHP5 я использовал такой код:

    Дополнительную информацию по использованию XSLT в PHP5 можно найти по адресу http://ru2.php.net/manual/ru/book.xslt.php.

    Мысли вслух

    «Товарищи, мы стоим на краю огромной пропасти! И я предлагаю сделать большой, решительный шаг вперёд!»

    © 2020 Антон Прибора. При копировании материалов с сайта, пожалуйста, указывайте ссылку на источник.

    Основные команды XSLT

    Читайте также:

    1. A) Основные термины и определения
    2. Borland C и его основные режимы с характерными окнами
    3. D. Основные принципы.
    4. I. Основные права граждан
    5. I. Основные правила и принципы переноса слов
    6. II ОСНОВНЫЕ ПРАВИЛА МЕР БЕЗОПАСНОСТИ
    7. II. Основные понятия
    8. II.3.3. Основные направления денежно-кредитной политики
    9. III. Основные задачи и функции поисково-спасательных формирований ПСС МЧС России.
    10. III.2. Основные методы и критерии разрешения педагогических конфликтов
    11. V1: Предмет, метод и основные категории статистики как науки
    12. XIV. Основные понятия и методы математической статистики.

    xsl:apply-templates — Применение XSLT шаблона

    Атрибуты: select — расширенное X-Path выражение (опционально). Текстовое содержание отсутствует.

    Описание: Команда рекурсивно вызывает XSLT шаблон xsl:template с атрибутом match, совпадающим с X-Path выражением select, для всех потомков текущего XML узла, соответствующих данному выражению. Если атрибут select не задан, для каждого потомка текущего XML узла рекурсивно будет вызываться соответствующий XSLT шаблон xsl:template.

    Введение в XSLT

    Преобразование формата XML-данных посредством преобразований расширяемого языка таблиц стилей (XSLT)

    Перед началом работы

    Данное руководство создано для разработчиков, которые хотят использовать XSLT для преобразования XML-данных в другие формы без необходимости программирования на Java™ или других языках.

    В данном руководстве подразумевается, что вы знакомы с XML, однако автор не вдается в какие-то тайные особенности этого языка, поэтому базового понимания вполне достаточно. За исключением небольшого раздела про расширения, вам не нужно иметь за плечами никакого особенного языка программирования. И даже в этом разделе идеи очень просты и применимы к любому языку программирования, который поддерживается процессором.

    О чем это руководство?

    Это руководство — о преобразованиях расширяемого языка таблиц стилей (XSLT). XSLT — это одна из базовых спецификаций, связанных с XML, позволяющая легко переводить XML-данные из одной формы в другую.

    В данном руководстве вы изучите:

    • Основы XSLT
    • Использование простых шаблонов
    • Публикацию данных
    • Управление пробелами
    • Основы XPath
    • Функции XPath
    • Циклы и условные операторы
    • Импорт и включение других таблиц стилей
    • Расширение XSLT
    • Переменные XSLT

    Начало работы

    Представьте на минуту, что у вас есть набор данных в XML. Возможно, вы предпочли хранить их таким образом из-за гибкости XML. Вы знаете, что сможете использовать их на разных платформах и практически с любым языком программирования. Но иногда вам придется менять форму вашего XML. Например, вам может понадобиться перевести данные в другой XML-формат, чтобы хранить их в другой системе, или в другую форму для представления, или еще для чего-нибудь.

    Например, у вас могут быть данные в XML, которые вы хотите опубликовать в Интернете, что означает перевод их в HTML. Конечно, вы могли бы вручную просмотреть документ и сделать в нем необходимые изменения, или может быть, вы подумали о том, чтобы загрузить XML в DOM, а затем вручную создать документ вывода.

    Что такое XSLT?

    Преобразования расширяемого языка таблиц стилей (XSLT) предоставляют способ для автоматического перевода XML-данных из одной формы в другую. Целевая форма — это обычно другой XML-документ, но не обязательно; вы можете преобразовать XML практически во что угодно, просто создав таблицу стилей XSLT и обработав данные. Если вы хотите изменить результаты, вы просто меняете таблицу стилей и обрабатываете XML заново. Здесь есть дополнительное преимущество, расширяющее возможности непрограммистов, например, дизайнеров, которые могут изменять таблицу стилей и влиять на результаты.

    Давайте посмотрим пример.

    Поставленная задача

    В данном руководстве мы возьмем XML-документ и преобразуем его в XHTML-документ, который можно отобразить как Web-страницу. Входные данные — это просто файл с рецептами (см. листинг 1).

    Листинг 1. Основные данные

    Замечание редактора: Эти рецепты –приведены просто для примера, так, как их представляет себе автор. Правильный рецепт для Gush’gosh (полученный от его жены, которая и готовит это блюдо) состоит из 1 фунта (0,454 кг) рубленой говядины, 1 фунта рожков, 1/2 стакана желтого сахара, 1 небольшого пакета (около 300 грамм) мелко нарезанного лука, 1 чайной ложки сушеного укропа и 1 небольшой банки томатной пасты, в которую добавляется желтый сахар.

    Конечно, это очень простой пример, поэтому вы не увязнете в деталях самих данных, однако в виде XML-данных можно представить что угодно — от процесса журналирования до финансов.

    Наша цель — преобразовать эти данные в XHTML-страницу, которая будет отображать рецепты по отдельности и форматировать их ингредиенты и инструкции по приготовлению (см. листинг 2).

    Листинг 2. Результат

    Вы можете отобразить этот результат в браузере, как показано на рисунке 1.

    Рисунок 1. Результат, отображенный в браузере

    Как уже упоминалось, конечной целью может быть любой формат, не только XHTML, и даже не обязательно XML.

    Давайте начнем с простых преобразований.

    Простая таблица стилей

    Самая простая таблица стилей — это просто XML документ, включающий XSLT-вывод (см. листинг 3).

    Листинг 3. Самая простая таблица стилей

    Обратите внимание на использование пространства имен xsl . Добавление этого пространства имен говорит процессору, какие элементы связаны с обработкой, а какие должны быть просто выведены. Элементы value-of говорят процессору вставить определенные данные в это место. Какие именно данные вставлять определяется содержимым атрибута select .

    Атрибут select состоит из выражения XPath. Подробнее XPath будет обсуждаться в разделе Подробнее об XPath, однако здесь вы можете видеть, что доступ к элементам «название», «ингредиенты» и «инструкция по приготовлению» происходит через иерархию документа. Мы начинаем с корневого элемента, /recipes , и от него движемся вниз.

    Как выполнить преобразование

    Простейший способ выполнить XML-преобразование — это добавить указание на таблицу стилей в XML и отобразить его в браузере (см. листинг 4).

    Листинг 4. Добавление в XML инструкции по обработке при помощи таблицы стилей

    Эта инструкция по обработке говорит браузеру извлечь таблицу стилей, расположенную в basicstylesheet.xsl, и использовать ее для преобразования XML-данных и вывода результатов. Если вы откроете наш XML-документ в браузере Microsoft® Internet Explorer®, то увидите результат, похожий на рисунок 2.

    Рисунок 2. Извлечение таблицы стилей и преобразование XML-данных

    Однако это не совсем то, что мы хотели получить. Если вы выберете в браузере Вид>Просмотр HTML-кода, то увидите изначальный XML. Чтобы увидеть результат преобразования, необходимо произвести это преобразование и создать выходной файл. Это можно сделать через командную строку, используя Java-код со следующей командой (см. листинг 5):

    Листинг 5. Преобразование документа через командную строку

    Если вы получите исключение ClassNotFoundException , возможно, вам нужно загрузить Apache Xalan (см. «Получить продукты и технологии» в разделе Ресурсы) и добавить включенные в него JAR-файлы в путь к классам.

    Выполнив преобразование, показанное в листинге 5, вы увидите, что файл result.html содержит следующий код (см. листинг 6).

    Листинг 6. Результаты

    Я добавил несколько интервалов для удобства чтения, однако здесь следует отметить пару моментов. Во-первых, листинг 6 отображает информацию только для одного рецепта. Во-вторых, ингредиенты слеплены вместе без каких-либо пробелов. Это тоже не тот результат, который мы хотели получить. К счастью, можно создать более точные шаблоны для отображения данных именно в той форме, в какой вы хотите.

    Добавление шаблонов

    От преобразования нет никакой пользы, если оно не приводит данные именно к той форме, которая нам нужна. Чтобы это сделать, нужно уметь использовать шаблоны, чему и посвящен данный раздел.

    Создание шаблонов

    Большинство таблиц стилей не имеют такой простой формы, какую вы только что видели в предыдущем разделе. Вместо этого они разбиваются на группу шаблонов, каждый из которых применяется к определенному типу данных. Давайте переведем нашу таблицу стилей в эту форму (см. листинг 7).

    Листинг 7. Переделанная таблица стилей

    Здесь информация не изменилась, за исключением того, что процессор смотрит на таблицу стилей и начинает с шаблона, совпадающего с корневым элементом документа, как указано в атрибуте match . Затем он выводит этот шаблон, включая все значения, так же как и раньше. Если вы выполните сейчас преобразование, то должны увидеть точно такие же результаты, как и в листинге 6.

    Но это не то, что мы хотим. Мы хотим иметь возможность форматировать ингредиенты и инструкции. Для этого мы можем создать отдельные шаблоны для каждого из этих элементов и включить их в таблицу стилей (см. листинг 8).

    Листинг 8. Создание дополнительных шаблонов

    Обратите внимание, что вместо того, чтобы просто вывести элемент value-of , мы теперь указываем таблице стилей применять соответствующие шаблоны к элементам ingredients и instructions. Затем мы создали отдельные шаблоны для этих элементов, задав их в атрибуте match . Добравшись до элемента apply-templates , процессор выбирает все элементы ingredients в документе. Затем он ищет шаблон для ингредиентов, а, найдя его, выводит этот шаблон. То же самое он делает с элементом instructions . Результат должен быть похож на изображенный на рисунке 3.

    Рисунок 3. Применение соответствующих шаблонов к элементам ingredients и instructions

    Так, это уже немного ближе, хотя бы понятно, что здесь два рецепта, однако вы вряд ли захотите объединять ингредиенты и инструкции для всех рецептов. К счастью, эту проблему можно решить лучшей организацией шаблонов.

    Публикация шаблонов

    Чтобы лучше организовать данные, обратим внимание на то, как мы разделяем и публикуем шаблоны. XSLT позволяет обрабатывать информацию итеративным образом. Например, можно поделить информацию на отдельные рецепты, а затем отформатировать инструкции и ингредиенты (см. листинг 9).

    Листинг 9. Выделение рецептов

    В данном случае таблица стилей выводит основную страницу (HTML), а затем просматривает каждый рецепт, выводя название, ингредиенты и инструкции для каждого рецепта. Опять-таки XPath мы будем изучать в разделе Подробнее об XPath, но в данном случае элемент recipe становится контекстным узлом, поэтому атрибуты select относятся к этому узлу так же как файлы к конкретному каталогу в файловой системе. Результат должен быть похож на рисунок 4.

    Рисунок 4. Элемент recipe становится контекстным узлом

    Отлично, формат приблизился к желаемому, однако нам все еще нужно отобразить фактическую информацию. Для этого надо изменить шаблоны ingredients и instructions (см. листинг 10).

    Листинг 10. Работа над шаблонами ingredients и instructions

    Важный момент при публикации шаблонов: вы указали процессору применять подходящие шаблоны к элементу ingredients , однако у нас нет специального шаблона для этого элемента. Если вы примените шаблон к элементу, а самого шаблона не будет, то данные просто не появятся. Но это не наш случай.

    Наоборот, мы воспользовались тем, что когда указали процессору применять подходящие шаблоны к элементу ingredients , он ищет не только элемент ingredients , но и дочерние элементы элемента ingredients . Таким образом, он находит шаблон для ингредиентов, в котором вы выводите количество, единицы измерения, название продукта и разрыв строки.

    То же самое мы сделали для инструкций, когда отформатировали их как элементы списка. Заметьте, что мы создали фактически упорядоченный список в основном шаблоне для рецепта, а затем отправили элементы для индивидуальной обработки.

    Результат должен быть похож на рисунок 5.

    Рисунок 5. Создание упорядоченного списка в основном шаблоне рецепта

    Определенно формат приближается к желаемому. Однако если вы посмотрите на вывод, то увидите, что проблема с пробелами все еще существует (см. листинг 11).

    Листинг 11. Недоработанный вывод

    Добавление пробелов

    Почему это случилось, если мы включали пробелы в таблицу стилей? Должны они были появиться в выводе? Разумеется, необязательно. Есть способы указать таблице стилей оставлять пробелы — они будут изучены в разделе Организация циклов и импорт — однако в некоторых случаях проще явно добавить текст в вывод (см. листинг 12).

    Листинг 12. Добавление текста

    Тем самым мы позаботились о недостающих пробелах. Точно так же с помощью элемента text , можно добавить в шаблон любой произвольный текст. (Помните, что только текст, а не элементы типа разрыва страницы.) Результатом будет такой вывод, какой нам нужен (см. листинг 13).

    Листинг 13. Окончательный вывод

    Результат показан на рисунке 6.

    Рисунок 6. Проблема отсутствующих пробелов решена

    Далее вы узнаете, как добавлять на страницу определенную информацию с помощью XPath.

    Основы XPath

    Возможность преобразовывать данные в форму, в какой вы желаете их видеть, требует понимания языка маршрутов XML, или XPath, который позволяет контролировать, какие именно данные публикуются и/или отображаются. Данный раздел объясняет основные понятия XPath и показывает, как создавать простые выражения.

    Что такое XPath?

    Вы должны были заметить, что важной частью функционирования таблицы стилей является возможность выбрать конкретную часть документа. Например, если вы хотите отобразить инструкции, то нужно знать, как на них ссылаться. В XSLT мы ссылаемся на информацию, используя выражения XPath.

    Выражение XPath может выбрать единственный узел или набор узлов, либо вернуть единственное значение, основанное на одном или более узлов в документе. До сих пор мы имели дело с очень простыми выражениями XPath, которые выбирают узел или узлы, спускаясь вниз по иерархической структуре. XPath предоставляет несколько способов для задания групп узлов на основании отношений, таких как родитель-потомок или предок-потомок. В данном руководстве мы изучим все эти отношения, называемые осями.

    Вы также узнаете о некоторых более мощных функциях XPath и о предикатах — это в основном условные утверждения, которые можно добавлять в выражения. Например, в разделе Настройка контекста вы увидите, как выбирать все элементы recipe в документе; предикаты позволяют выбрать только конкретный элемент на основании конкретных критериев.

    Наконец, вы узнаете о еще более мощных функциях, которые позволяют использовать многие типы логики, которые используются в процедурных программах.

    Давайте начнем с изучения контекста выражения.

    Настройка контекста

    Первым шагом в понимании XPath является понимание того, что полученные результаты в большой степени определяются текущим контекстным узлом. Контекстный узел можно считать своеобразным знаком «ты находишься здесь», от которого можно двигаться в различных направлениях согласно выражению XPath. Например, рассмотрим простую таблицу стилей в листинге 14.

    Листинг 14. Демонстрация контекста

    Здесь есть новый элемент — copy-of . Там, где value-of выводит содержимое элемента, copy-of делает именно то, о чем говорит его название, и выводит фактический узел, на который ссылается атрибут select .

    В данном случае в атрибуте select содержится одно из простейших возможных выражений XPath. Одиночная точка (.) – это ссылка на данный контекстный узел, как в файловой системе, когда вы хотите сослаться на «текущую директорию, вне зависимости от того, что это за директория.» Поэтому если вы выполните это преобразование, то получите результат, как в листинге 15.

    Листинг 15. Простейшее преобразование

    Вы видите, что это просто повторение того же документа; это потому, что контекстный узел, как указано атрибутом шаблона match, — это корень документа, или /. Если вы измените контекстный узел, вывод изменится. Например, вы можете установить контекстный узел на первый рецепт (см. листинг 16).

    Листинг 16. Перемещение контекстного узла

    Теперь, запустив преобразование, вы увидите разницу (см. листинг 17).

    Листинг 17. Результаты

    Так как мы переместили контекстный узел, вывод изменился. Это важно, когда вы хотите выбрать узел относительно контекстного узла. Например, вы можете выбрать только заголовок рецепта (см. листинг 18).

    Листинг 18. Выбор только заголовка

    Здесь вы выбираете элемент name , расположенный на один уровень ниже, чем текущий контекстный узел, поэтому результат будет как в листинге 19.

    Листинг 19. Результаты

    Мы изучим задание узлов по номеру позже, а пока отметим, что мы можем переместить контекстный узел во второй рецепт (см. листинг 20).

    Листинг 20. Еще одно перемещение контекстного узла

    (Не обращайте внимания на еще один шаблон, он нужен, чтобы не появлялся текст другого рецепта.)

    Мы можем видеть, что результирующее преобразование показывает это изменение контекста (см. листинг 21).

    Листинг 21. Результаты

    Для чего нужны оси

    Теперь, когда мы знаем, откуда мы начинаем, было бы полезно узнать, куда можно двигаться. До сих пор мы использовали очень простые выражения XPath, похожие на иерархию в файловой системе, однако XPath предоставляет гораздо больше возможностей. Например, до сих пор вы выбирали только дочерние элементы, однако вы можете также искать родителей конкретного узла, а также его потомков или предков.

    Для начала давайте поговорим о системе обозначений. Мы использовали упрощенную, укороченную форму запроса потомков. В «длинной форме» выражения задаются как child::name вместо ./name

    В обоих случаях вы задаете любой узел, который является потомком контекстного узла, а также является элементом name . Вы также можете связать их вместе, как в предыдущем случае, используя /child::recipes/child::recipe вместо /recipes/recipe .

    Потомки

    Возможно, вы недоумеваете, зачем мучаться с длинной формой, если короткая настолько проще. Это не было бы нужно, если бы единственное, что вы могли бы делать — это выбор потомков. Однако эту нотацию также можно использовать для выбора других отношений. Например, выражение XPath descendant::instruction выбирает все элементы instruction, которые являются потомками контекстного узла, а не только дочерние элементы. Кроме того, можно комбинировать инструкции. Например, вы можете выбрать все инструкции второго рецепта: /recipes/recipe[2]/descendant::instruction .


    Одной из разновидностей оси потомков является ось потомок-или-сам-элемент, которая выбирает заданный узел из всех потомков, а также ищет в самом контекстном узле. Например, выражение descendant-or-self::instructions выбирает все узлы instruction в контекстном узле и ниже его. Обычным сокращением для этой оси является двойная косая черта, //. Это означает, что выражения: /recipes/recipe[2]//instructions и //instructions выбирают все инструкции для второго рецепта и все инструкции в документе, соответственно. Этот второй пример очень широко применяется, он удобен, когда вы хотите просто выбрать все элементы определенного типа в документе.

    Атрибуты

    Еще одна общая задача, с которой вы столкнетесь — это необходимость выбрать атрибут для конкретного элемента. Например, вы, возможно, захотите выбрать recipeId для конкретного рецепта. Выражение /recipes/recipe/attribute::recipeId выбирает атрибут recipeId для всех элементов recipe . Эта ось также имеет сокращенную форму: это же выражение можно записать так: /recipes/recipe/@recipeId .

    Родители

    Все, что мы видели до этого, переносило нас вниз по дереву иерархии, но также существует возможность пойти вверх, выбрав предка конкретного узла. Предположим, что контекстным узлом была одна из инструкций, а вы хотите вывести recipeId для текущего рецепта. Вы можете сделать это следующим образом: ./parent::node()/parent::node()/@recipeId .

    Это выражение начинается в текущем узле — instruction -, а затем двигается к предку этого узла — элементу instructions — а затем к предку ТОГО элемента — recipe -, а затем к соответствующему атрибуту. Возможно, вам лучше знакома сокращенная форма: ./../../@recipeId .

    Теперь давайте посмотрим, как задаются некоторые условия.

    Более продвинутые возможности XPath

    В большинстве случаев уже рассмотренных приемов достаточно. Однако нередко встречаются ситуации, требующие большей избирательности. Данный раздел показывает, как использовать предикаты для выбора узлов, основанных на конкретных критериях, и дает представление о некоторых функциях, встроенных в XPath.

    Использование предикатов

    Зачастую требуется не просто любой узел, а конкретный узел, выбранный на основе конкретных условий. Вы ранее уже видели пример, когда использовали выражение /recipes/recipe[2]//instructions . Это на самом деле сокращенная версия выражения /recipes/recipe[position() = 2]//instructions , которое означает, что процессор XPath должен пройти через каждый элемент recipes (конечно, такой элемент только один) и для каждого элемента recipes пройти через каждый элемент recipe. Для каждого элемента recipe проверить истинность выражения position() = 2 . (Другими словами, есть ли в списке этот второй рецепт?) Если это предложение, называемое предикатом, истинно, то процессор использует этот узел и продолжает, возвращая любые инструкции.

    С помощью предикатов можно сделать множество вещей. Например, можно вернуть только рецепты, в которых есть название: /recipes/recipe[name] . Это выражение просто проверяет, существует ли элемент name — потомок элемента recipe . Также можно поискать конкретные значения. Например, можно возвращать только элементы, которые называются «A balanced breakfast»: //recipe[name=»A balanced breakfast»] .

    Имейте в виду, что предикат просто говорит процессору, возвращать ли текущий узел, поэтому в данном случае возвращается элемент recipe, а не имя. С другой стороны, можно указать процессору возвратить только название первого рецепта при помощи любого и этих двух выражений (см. листинг 22).

    Листинг 22. Возвращение только названия первого рецепта

    В первом выражении сначала мы выбираем все элементы recipe , а затем возвращаем только тот, у которого есть атрибут элемента recipeId , равный 1. Найдя этот узел, мы двигаемся к его дочернему узлу, который называется name, и возвращаем его. Во втором выражении сначала отыскиваются все элементы name , а затем выбирается только тот, у чьего родителя имеется атрибут 1. В любом случае, вы получите один и тот же вывод (см. листинг 23).

    Листинг 23. Вывод

    Функции

    XPath также предоставляет ряд функций. Некоторые из них относятся собственно к узлам, — например, те, которые ищут конкретную позицию, — некоторые обрабатывают строки, некоторые , — такие как суммирование, — с числами, некоторые с булевскими значениями.

    Функции, связанные с узлами

    Функции, связанные с узлами, помогают, например, выбрать конкретный узел в зависимости от позиции. Например, вы можете специально запросить последний рецепт: //recipe[last()] . Данное выражение выбирает все элементы recipe , а затем возвращает только последний. Вы также можете использовать функции отдельно, вместо того чтобы использовать их как часть предиката. Например, вы можете специально запросить посчитать элементы recipe: count(//recipe) .

    Вы уже видели функцию position() и то, как она работает. Другие функции, связанные с узлами, включают id() , local-name() , namespace-uri() и name() .

    Строковые функции

    Большинство строковых функций предназначено для обработки строк, а не для их проверки, за исключением функции contains() . Функция contains() показывает, является ли данная строка частью большего целого. Это позволит, например, вернуть только узлы, содержащие определенные строки, такие как: //recipe[contains(name, ‘breakfast’)] .

    Это выражение возвращает элемент recipe, который содержит в своем элементе name строку «breakfast».

    Функция substring() позволяет выбрать конкретный диапазон символов из строки. Например, выражение: substring(//recipe[2]/name, 1, 5) возвращает A bal .

    Первый аргумент — это полная строка, второй — позиция первого символа, а третий — это длина диапазона.

    Среди прочих строковых функций имеются: concat() , substring-before() , substring-after() , starts-with() и string-length() .

    Числовые функции

    Числовые функции включают функцию number() , которая переводит значение в числовое, чтобы другие функции могли с ним работать. Числовые функции также включают: sum() , floor() , ceiling() и round() . Например, вы можете найти сумму всех значений recipeId при помощи выражения: sum(//recipe/@recipeId) .

    Конечно, особого повода проводить подобное вычисление нет, однако это просто числовое значение, приведенное для примера.

    Функция floor() находит наибольшее целое, которое меньше или равно данному значению, а функция ceiling() находит наименьшее целое, которое больше или равно данному значению. Функция round() работает традиционным образом — округляет (см. листинг 24).

    Листинг 24. Результаты числовых функций

    Булевы функции

    Булевы функции наиболее полезны при работе с условными выражениями, о которых будет рассказано в разделе Условная обработка. Возможно, наиболее полезной функцией является not() , которая может быть использована для определения того, что определенный узел не существует. Например, выражение //recipe[contains(name, ‘breakfast’)] возвращает каждый рецепт, содержащий в элементе name строку «breakfast». Но что, если вам нужны все рецепты, кроме завтрака? Можно использовать выражение: //recipe[not(contains(name, ‘breakfast’))] .

    Другие булевы функции включают true() и false() , которые возвращают константы, и boolean() , которая преобразует значение в булево, чтобы его можно было использовать в качестве проверочного.

    Организация циклов и импорт

    Рассмотрим еще два важных аспекта использования таблиц стилей XSLT: создание циклов и импортирование внешних таблиц стилей.

    Организация циклов

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

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

    Листинг 25. Прямое применение стилей с использованием циклов

    Конструкция цикла очень похожа на структуру for-each , в честь которой она названа. Подобно тезке, каждый экземпляр цикла несет в себе следующее значение списка. В Java-программировании это могло бы быть следующее значение в массиве; здесь это следующий узел в совокупности узлов, возвращенных выражением XPath в атрибуте select . Это означает, что когда вы первый раз выполняете первый цикл, контекстным узлом является первый элемент ingredient . Это позволяет выбрать потомков этого элемента qty, unit и food и добавить их в документ так же, как это было сделано ранее при помощи шаблона. То же самое и с инструкциями, за исключением того, что они просто выводятся напрямую.

    Результаты идентичны тем, что получаются при публикации через шаблоны — почти. Каждый шаблон добавляется к документу как индивидуальная строка, но так как нам необходимо обрабатывать эту информацию как один шаблон, мы теряем множество пробелов, которые видели раньше (см. рисунок 7).

    Рисунок 7. Результаты

    Для некоторых XML-приложений это имеет значение, но здесь мы используем HTML, поэтому это значения не имеет. Однако помните об этом, когда решаете, какой метод использовать.

    Включение и импорт таблиц стилей

    Другая вариация таблиц стилей касается их структуры. До сих пор вся наша информация хранилась в единственной таблице стилей. Однако в некоторых случаях бывает полезно разбить ее на отдельные таблицы стилей. Такая модульность может облегчить поддержку, а также гибкость, позволяя использовать различные таблицы стилей для различных целей. Например, мы можем создать две различные таблицы стилей, одна из которых будет использоваться для ингредиентов (см. листинг 26).

    Листинг 26. Файл ingredients.xsl

    Также можно создать отдельную таблицу стилей для инструкций (см. листинг 27).

    Листинг 27. Файл instructions.xsl

    Эти шаблоны идентичны шаблонам из действующей таблицы стилей. Их можно добавить к таблице стилей посредством включения (см. листинг 28).

    Листинг 28. Включение таблиц стилей

    Хотя здесь мы разместили таблицы стилей в той же директории, что и основную таблицу, делать это не обязательно: атрибут href может содержать любой доступный URL. Обратите внимание, что мы отсылаем процессор на поиск шаблонов для элементов ingredients и instructions , которых нет в этом файле. Однако если обработать таблицу стилей, результат получится точно тот же, как если бы шаблоны были включены напрямую, а не через элемент include (см. рисунок 8).

    Рисунок 8. Результаты

    Элемент include дает тот же результат, как если бы мы добавили содержимое начиная с данной точки. Семантически они идентичны. С другой стороны, есть еще один способ включения информации — импорт.

    XSLT позволяет импортировать таблицу стилей в начало файла. Почему в начало? Потому что целью импорта таблицы стилей является возможность корректировки любых шаблонов, являющихся частью импорта. Например, мы можем импортировать шаблон ingredients и откорректировать его (см. листинг 29).

    Листинг 29. Импорт таблицы стилей

    Здесь мы фактически заменили один шаблон двумя, которые заменяют шаблоны в импортированной таблице стилей (см. рисунок 9).

    Рисунок 9. Результаты

    Обратите внимание, что, так как иерархия зависит от расположения, того же результата можно было бы добиться и с помощью включения. Однако XSLT позволяет использовать атрибут priority , чтобы задать приоритет шаблонов при обработке импорта.

    Расширение XSLT

    Мы увидели, как сделать XSLT более похожим на программирование. Как насчет добавления к нему фактического программирования? Давайте взглянем на добавление функциональности Java к таблице стилей XSLT.

    Во-первых, следует отметить, что хотя механизм расширения является частью рекомендаций XSLT, рассматриваемая здесь реализация специфична для процессора Xalan XSLT. Основные идеи практически одинаковы для других процессоров, однако для уточнения деталей вам придется сверяться с документацией.

    Далее мы создадим расширение, которое позволит нам масштабировать рецепт на несколько порций.

    Элементы расширения

    Расширение XSLT производится с помощью различных методик. Первая — это использование элементов extension . Элемент extension — это элемент в пространстве имен, который указывает на класс Java. Взгляните, например, на следующий элемент extension (см. листинг 30).

    Листинг 30. Использование элемента extension

    Мы создали пространство имен, которое соответствует классу comp.backstop.RecipeScaler , который включает в себя статический метод под названием scaleMessage (см. листинг 31).

    Листинг 31. Класс RecipeScaler

    Добравшись до элемента, процессор видит префикс пространства имен scaler: и знает, что он обозначен как префикс элемента extension, и таким образом понимает, какой класс обозначен в определении пространства имен. Вызываемый им метод отвечает локальному имени элемента — scaleMessage . Сам метод получает два аргумента, из которых мы фактически используем один. Параметр context ссылается на контекст процессора, который позволяет взглянуть на элементы, относящиеся к элементу extension , однако мы просто займемся самим элементом extension . Так как мы получаем этот элемент как параметр метода, мы можем извлечь значения любых атрибутов, добавленных к этому элементу, таких как servings в данном случае. Текст, возвращенный методом, добавляется к выводу на месте элемента extension .

    Это означает, что если применить таблицу стилей, мы получим результаты, показанные на рисунке 10.

    Рисунок 10. Результаты элемента extension

    Элементы extension могут быть весьма полезны, хотя и несколько сложны в использовании.

    Функции extension

    Еще один способ добавить функциональность при помощи таблиц стилей — это использование функций extension, которые несколько проще реализовывать, чем элементы extension. Например, мы можем создать функцию, которая умножает количество ингредиентов и количество порций (см. листинг 32).

    Листинг 32. Метод scaleIngredient()

    Добавление этой функции в таблицу стилей идентично добавлению элемента extension, в котором уже есть карта пространства имен для класса (см. листинг 33).

    Листинг 33. Добавление функции extension

    Учтите, что вызов функции включает префикс пространства имен. Как и ранее, процессор видит префикс и знает, что надо выполнить вызов класса RecipeScaler . В результате количество ингредиентов умножается на два (см. рисунок 11).

    Рисунок 11. Использование функции extension

    Хотя данный код и работает, поддерживать его сложно. Давайте посмотрим, как упростить поддержку.

    Программирование XSLT

    Прежде, чем закончить изложение, рассмотрим два аспекта XSLT, которые предоставляют некоторые возможности, характерные для обычных языков программирования.

    Переменные XSLT

    Прекрасно, что мы можем выполнить функцию, но дело кончилось константой, запрятанной в глубине таблицы стилей. Не лучше ли было бы задавать переменные в начале страницы? Конечно, да (см. листинг 34).

    Листинг 34. Задание переменной

    XSLT позволяет создавать переменные; в ссылке используется знак доллара ($), который можно увидеть в листинге. Если применить таблицу стилей, можно увидеть два эффекта (см. рисунок 12).

    Рисунок 12. Использование переменной

    Обратите внимание, что ингредиенты были умножены на количество порций, как и ожидалось. Однако если вы посмотрите внимательнее, то увидите, что элемент extension сработал неверно, приняв переменную за строку, вместо того чтобы использовать значение самой переменной. Это не сбой; спецификация не требует, чтобы процессор что-либо делал со значениями атрибутов перед обработкой элемента extension. Поэтому нам надо как-то избежать этой проблемы.

    Условная обработка

    Первое, что мы можем сделать — это использовать условную обработку, чтобы сообщение отображалось, только если оно нужно. Например, см. листинг 35.

    Листинг 35. Использование элемента if

    Содержимое элемента if , заданное атрибутом test, должно быть равно true (истина). Если это не так, что и произошло в данном случае, вывод не появится вовсе (см. рисунок 13).

    Рисунок 13. Результаты предложения if

    В том виде, в каком оно написано, предложение не имеет особого смысла; если значение больше единицы, элемент extention отобразится со значением «3.» Лучше использовать множественный выбор (см. листинг 36).

    Листинг 36. Элемент choose

    В данном случае у нас имеется комбинация элементов if-then-else и предложения case из традиционных языков программирования. Элемент choose работает как контейнер, однако элемент when отображает его содержимое, только если его атрибут test равен true (истина). Наконец, если ни один из элементов when не равен true (истина), процессор отображает содержимое элемента otherwise .

    Результат получается такой, какого следует ожидать (см. рисунок 14).

    Рисунок 14. Результат

    Теперь вы можете более гибко задать отображение большего количества порций, или подстроиться под другие условия.

    Заключение

    Подведение итогов

    Данное руководство позволило продвинуться от начального знакомства с преобразованиями XSLT до составления достаточно сложных таблиц стилей. Сначала вы познакомились с основами таблиц стилей, затем с выражениями XPath — одной из основ XSLT. В последней части данного руководства были рассмотрены некоторые более сложные аспекты таблиц стилей XSLT — переменные, условная обработка и расширения. В результате у вас теперь должно быть достаточно знаний, чтобы делать с таблицами стилей XSLT практически все необходимое — или хотя бы понимать, что еще надо выяснить, если столкнетесь с проблемой.

    Способ: использование преобразований XSLT с файлами обмена данных XML проекта How to: Use XSLT Transformations with Project XML Data Interchange Files

    Таблица стилей преобразования (XSLT) standard указывает определение языка для преобразования XML-данных. The Extensible Stylesheet Language Transformation (XSLT) standard specifies a language definition for XML data transformations. XSLT используется для преобразования XML-документов в документы XHTML или в других XML-документов. XSLT is used to transform XML documents into XHTML documents, or into other XML documents. В этой статье показано, как использовать XSLT с помощью Microsoft Office Project 2007 XML обмена данными файлов для фильтрации и отображения сведений о проекте. This article shows you how to use XSLT with Microsoft Office Project 2007 XML Data Interchange files to filter and display project information. (Сведения в этой статье был предоставили Джессика Britton корпорации Майкрософт.) (The content of this article was contributed by Jessica Britton, Microsoft Corporation.)

    Сведения о сохранении проекты в виде обмена данными Project XML-файлов можно Сохранение и открытие проектов в формате XML. For information about saving projects as Project XML Data Interchange files, see Saving and Opening Projects in XML Format.

    Таблицы стилей XSLT — это XML-документ, состоит из комбинации XHTML разметки, правила шаблона XSLT и XPath операторов, которые работают вместе. An XSLT stylesheet is an XML document that consists of a combination of XHTML markup, XSLT template rules, and XPath statements that work together.

    Разметка XHTML определяет среды отображения, представленных в XML-данных. XHTML markup defines the display environment that XML data is presented in.

    Правила шаблона XSLT предоставлены инструкции для преобразования XML-элемент источника определенным образом. XSLT template rules provide instructions for transforming a source XML element in a particular way.

    Операторы XPath определите определенных элементов XML-документа. XPath statements identify specific elements within an XML document.

    При XML-элемент соответствует шаблону XPath, вызывается связанного шаблона правила преобразования XSLT. When an XML element matches an XPath pattern, the associated XSLT template rule is invoked. Преобразованные данные выводятся в платформе отображения, указанный с помощью разметки XHTML. The transformed data is then rendered in the display framework specified by the XHTML markup.

    Дополнительные сведения о правилах шаблон XSLT и XPath операторов воспользуйтесь ссылками в конце этой статьи. For more information about XSLT template rules and XPath statements, see the links at the end of this article.

    Отображение сведений о проекте с помощью XSL-преобразований Displaying Project Information by using XSLT Transformations

    Процедура 1. Procedure 1. Чтобы создать таблицу стилей XSLT: To create an XSLT stylesheet:

    Создание файла XSLT для вашей таблицы стилей. Create an XSLT file for your stylesheet. При работе в Microsoft Visual Studio 2005 можно использовать шаблон XSLT-файл (в Visual Studio откройте меню файлвыберите команду Создатьи выберите пункт файл. If you are working in Microsoft Visual Studio 2005, you can use the XSLT File template (in Visual Studio, click File, point to New, and then click File. Этот шаблон предварительно заполняется в XML-коде показано в следующем примере. This template is prepopulated with the XML code shown in the following example. Если вы работаете в качестве другого текстового или XML-редактора, скопируйте этот шаблон XML и вставьте его в XSLT-файл. If you are working in another text or XML editor, copy this template XML and then paste it into your XSLT file.

    Удалите следующий XML-код комментарии. Delete the following XML code comment. Здесь указывается, где написании кода XSLT. This is where you write your XSLT code.

    Создание кода XSLT. Create your XSLT code. Код XSLT, показано в следующем примере выполняет следующие действия. The XSLT code shown in this example does the following:

    Отображает текстовое значение имя дочернего элемента проекта в заголовок. Displays the text value of the Name child of the Project element in a header.

    Проверяет сводки дочерним элементом каждой задачи для просмотра, если значение равно 0 (false). Tests the Summary child of each Task element to see if the value is 0 (false).

    Проверка важных дочерних каждого элемента задачи для просмотра, если значение равно 1 (true). Tests the Critical child of each Task element to see if the value is 1 (true).

    Отображает данные для особо важные задачи, которые не являются суммарными задачами полужирным шрифтом. Displays data for critical tasks that are not summary tasks in bold.

    Отображает данные для некритические задачи, которые не являются суммарными задачами. Displays data for noncritical tasks that are not summary tasks.

    Сортировка сведения о ресурсах по текстовое значение дочернего имя для каждого элемента ресурсов. Sorts resource information alphabetically by the text value of the Name child of each Resource element.

    Проверяет дочернего превышение доступности для каждого элемента ресурсов является ли значение 1 (true). Tests the Overallocated child of each Resource element to see if the value is 1 (true).

    Отображение сортированных ресурсе только с превышением доступности ресурсов. Displays sorted resource data for only overallocated resources.

    Сохраните файл как ProjectTransform.xslt. Save the file as ProjectTransform.xslt.

    После создания таблицы стилей XSLT, необходимо связать файл XML для проекта к нему, добавив инструкции по обработке. After you create the XSLT stylesheet, you must link your Project XML file to it by adding processing instructions. Процедура 2 показано, как связать ProjectTransform.xslt файл, созданный в процедуру 1 для всех файлов XML для проекта. Procedure 2 shows you how to link the ProjectTransform.xslt file created in Procedure 1 to any Project XML file.

    Процедура 2. Procedure 2. Чтобы изменить файл XML для проекта для использования таблицы стилей XSLT: To modify the Project XML file to use the XSLT stylesheet:

    Откройте файл XML для проекта в Visual Studio или в другом текстовом редакторе или редакторе XML. Open a Project XML file in Visual Studio, or in another text or XML editor.

    Вставьте следующую строку кода после объявления XML — это первая строка в проект XML-файл. Insert the following line of code after the XML declaration, which is the first line in the Project XML file.

    Удалите объявление пространства имен XML из внутри элемента проекта, который представляет собой корневой элемент проекта XML-файла. Delete the XML namespace declaration from inside the Project element, which is the root element of the Project XML file. Если не удаляйте объявление пространства имен, встроенного в элемент проекта, операторы XPath завершится с ошибкой в соответствии с элементами в проект XML-файл. If you do not delete the namespace declaration that is embedded in the Project element, XPath statements will fail to match elements in the Project XML file.

    После выполнения действия 2 и 3, первые три строки проект XML-файл должен выглядеть как в следующем примере кода. After you perform Steps 2 and 3, the first three lines of your Project XML file should look like the following code example.

    Сохраните файл XML для проекта. Save the Project XML file.

    Мы рекомендуем сохраните файл с именем файла, отличный от исходное имя файла XML для проекта, так как изменения, внесенные в шаге 3 разорвать связь проекта XML-файла из проекта данных Interchange схемы XML. We recommend you save the file by using a file name that is different from the original Project XML file name, because the changes made in Step 3 disassociate the Project XML file from the Project XML Data Interchange Schema.

    Просмотр преобразованный файл XML для проекта. View the transformed Project XML file. Можно выполнить преобразования XSLT в Visual Studio, установив таблицы стилей проекта XML-файла для ProjectTransform.xslt и затем выбрав команду Показать вывод XSLT в меню XML . You can perform the XSLT transformation in Visual Studio by setting the Stylesheet property of the Project XML file to ProjectTransform.xslt, and then selecting Show XSLT Output from the XML menu.

    Можно также открыть проект XML-файл в Internet Explorer 7, Microsoft Office Word 2007 или любого другого приложения, поддерживающего XSLT. You can also open the Project XML file in Internet Explorer 7, Microsoft Office Word 2007, or any other application that supports XSLT.

    На рисунке 1 показано преобразованные выходные данные проекта XML-файла в Word 2007. Figure 1 shows the transformed output of a Project XML file in Word 2007. При открытии файла XML для проекта по умолчанию только данные представления данных отображается. When you open the Project XML file, by default the Data only data view is displayed. Чтобы просмотреть преобразованные выходные данные необходимо выбрать представление данных ProjectTransform.xslt в области XML-документа . To see the transformed output you must select the ProjectTransform.xslt data view in the XML Document pane.

    Рис. 1. Figure 1. XML-файл преобразованного проекта Transformed Project XML file

    Постраничная навигация в xml документах

    Содержание

    Отображение документа с постраничной навигацией табличной части

    Чем больше размер документа пересылаемого через ЭДО, тем больше времени необходимо на его визуализацию. Визуализация больших xml документов (>1Mb) в личном кабинете может занимать несколько некомфортных секунд. Чтобы сделать просмотр документов всегда быстрым и без задержек следует при разработке визуализаций документов, которые могут быть потенциально большими, применять технологию постраничного показа табличной части. В визуализацию документа добавляется анализ его размера. Если документ большой (например, количество строк табличной части больше 50), то табличная часть выводится постранично, а остальные части документа (шапка, подвал) показываются в зависимости от номера текущей страницы.

    Данная технология касается только отображения документа на экране. При печати или при сохранении в PDF, документ в любом случае будет выведен в полном объеме без постраничной навигации.

    Общая схема изменений в xslt:

    1. В xslt добавляются несколько глобальных служебных переменных, которые хранят в себе информацию о номере текущей отображаемой страницы, количестве записей таблицы, количестве страниц, которые будут показываться.
    2. В корневом темплейте добавляется вызов служебного div-а, который отвечает за постраничное отображение документа. Этот блок div имеет свой идентификатор и параметры, которые заданы разработчиками.
    3. Показ шапки и подвала документа настраивается в зависимости от номера текущей страницы. Информацию в шапке, например, показывать только на первой странице, а подвал – только на последней. Однако, рекомендуется показывать шапку и подвал всегда и сделать только навигацию по страницам.
    4. При отображении строк табличной части добавляются условия показа строк в зависимости от номера текущей страницы и количества записей на странице.

    Подробная схема изменений в xslt

    Глобальные переменные

    В начале xslt необходимо объявить 4 глобальные переменные:

    1. РазмерСтраницы – будет содержать в себе количество записей, которое должно отображаться на странице. Значение по-умолчанию: 0. В момент отображения документа автоматически заполняется значением из поля «Размер страницы» в форме добавления способа представления.
    2. Страница – хранит в себе текущую отображаемую страницу. Значение по-умолчанию: 0. Значение этой переменной меняется автоматически.
    3. КоличествоЗаписей – в эту переменную необходимо записать общее количество строк табличной части документа которые будут разнесены по страницам.
    4. КоличествоСтраниц – результат деления общего количества записей на размер страницы, округленный в большую сторону, или 1, если документ всегда должен отображаться на одной странице.

    Пример записи переменных:

    Добавление служебного div

    В корневом темплейте ( ) перед строкой необходимо добавить условие вывода служебного div-а, который при отображении документа позволит добавить постраничную навигацию:

    Вывод общей информации документа

    Если какую либо информацию необходимо выводить только на первой странице, то перед темплейтом (-ами) необходимо добавить условие:

    Если какую либо информацию необходимо выводить только на последней странице, то перед темплейтом (-ами) необходимо добавить условие:

    Если перед темплейтом, который что-то показывает, нет условий указанных выше, то результат работы темплейта будет выводится на каждой странице.

    Вывод табличной части с навигацией по страницам

    Перед отображением табличной части необходимо добавить условие, которое будет показывать строки в зависимости от того какой размер страницы: Если размер страницы больше 0 то запускается логика показа строк постранично. Если размер страницы 0, то показываем все строки на одной странице.

    В первом случае для того чтобы на странице выводить необходимое количество записей, учитывая при этом смещение (например, при размере страницы 20, на второй странице должны показываться строки с 21 по 40) необходимо: Добавить переменную в которой будет хранится порядковый номер первой строки на странице:

    Добавить переменную в которой будет хранится порядковый номер последней строки на странице:

    При вызове темплейта строки в условие отбора добавить отбор по позиции. Т.е. темплейт показа строки должен работать на те строки у которых текущая позиция больше или равна переменной startPosition и меньше endPosition:

    Метод вывода: XML

    Метод вывода: XML

    Формально при использовании метода вывода XML процессор XSLT создает хорошо сформированный внешний объект XML, который можно разобрать на общих условиях. Если корневой узел результирующего дерева имеет единственный дочерний узел-элемент и не имеет текстовых дочерних узлов. Тогда объект будет также хорошо сформированным документом XML.

    При использовании метода вывода XML атрибут version устанавливает версию XML результата. Заметьте, что если процессор XSLT не поддерживает эту версию XML, он будет использовать ту версию XML, которую поддерживает. По умолчанию установлено значение 1.0.

    Атрибут encoding устанавливает кодировку для результирующего документа. Процессоры XSLT должны поддерживать, по крайней мере, значения «UTF-8» и «UTF-16». Если процессор XSLT работает с другими значениями и не поддерживает указанную кодировку, он может сгенерировать ошибку. Если он этого не сделает, процессор должен использовать вместо нее UTF-8 иди UTF-16. Процессор XSLT не должен использовать кодировку, которая не была принята консорциумом W3C (см. www.ww3.org/TR/REC-xml). Если никакой атрибут кодировки не указан, по умолчанию процессор XSLT должен выбрать «UTF-8» или «UTF-16».

    ОБРАБОТКА НЕИЗВЕСТНЫХ СИМВОЛОВ

    Если результирующий документ содержит символ, который не может быть представлен в кодировке, используемой процессором XSLT для вывода, символ допустимо вывести как ссылку на символ. Если это невозможно, процессор XSLT должен сгенерировать ошибку.

    Как и в случае с методом вывода HTML, если атрибут indent установлен в «yes», метод вывода XML может добавить или удалить символы-разделители в результирующее дерево для того, чтобы выровнять результат. Значение по умолчанию — no. Заметьте, что если символы-разделители отбрасываются, информационное множество результирующего XML-документа должно быть таким же, как если бы символы-разделители вообще не добавлялись и не удалялись для выравнивания документа.

    ВЫРАВНИВАНИЕ ДОКУМЕНТОВ СО СМЕШАННЫМ СОДЕРЖИМЫМ

    Для документов со смешанным содержимым лучше не устанавливать атрибут indent в «yes», поскольку это вносит путаницу в работу процессора XSLT.

    При помощи атрибута cdata-section-elements можно задать разделенный символами-разделителями список имен элементов, чье содержимое должно трактоваться как разделы CDATA . Например, если установить атрибут cdata-section-elements в « DATA »:

    то следующий элемент буквального результата:

    будет преобразован в:

    Кроме того, метод вывода XML будет выводить в результирующий документ объявление XML, если только атрибут omit-xml-declaration не будет установлен в yes . Как правило, объявление XML, помещаемое в результирующий документ, обычно включает версию XML (что обязательно) и информацию о кодировке (хотя формально информация о кодировке в документах XML не обязательна). Если задан атрибут standalone , результирующий документ должен включать объявление отдельного документа с тем же значением, что и значение у атрибута standalone .

    При использовании атрибута doctype-system процессор создает объявление типа документа непосредственно перед первым элементом. В этом случае имя, следующее за , будет именем корневого элемента. Заметьте, что если вы также используете атрибут doctype-public , процессор XSLT выведет « PUBLIC », вслед за ним открытый идентификатор и затем системный идентификатор. Если вы не используете атрибут doctype-public , процессор выведет « SYSTEM » и вслед за ним системный идентификатор. Теоретически атрибут doctype-public должен игнорироваться, если не задан также атрибут doctype-system , хотя большинство процессоров, кажется, не следуют этому правилу. Мы увидим, как работать с атрибутами doctype-public и doctype-system в этой главе при преобразовании XML в XHTML.

    Наконец, для метода вывода XML значением по умолчанию для атрибута media-type является « text/xml ».

    Вы уже встречали в этой книге многие XML-XML преобразования. Например, преобразование из главы 4 просто копировало один документ XML в другой. Обратите внимание на метод вывода, который установлен в XML:

    XSLT шпаргалка:

    В данной статье хотелось бы рассказать про xslt конструкцию .

    Данная конструкуия является, наверно, самой простой и понятной. Она просто выводит то, что вы ей указали вывести. Это может быть текст внутри узла, содержимое атрибута и т.д. Позже, мы рассмотрим несколько примеров использования .
    Для начала посмотрим, что нам говорит о данной конструкции интернет:

    Элемент — Вставляет значение выбранного узла в виде текста.

    По факту, я бы сказал, что данная конструкция выводит в виде текста не только значение узла в виде текста, но и значение атрибута, параметра и переменной.
    У конструкции есть два атрибута:

    • select — который указывает что именно вы хотите вывести. Тут можно поставить xPath выражение, которое укажет на какой-то узел или атрибут, название переменной или параметра, текст или число, какие-то xPath выражения с функциями, например — математические.
    • disable-output-escaping — атрибут, указывающий нужно ли экранировать содержимое, которое мы выводим. По умолчанию равен значению «no«. Если вы выводите html текст, то стоит поменять значение данного атрибута на «yes» иначе все теги, например

    Давайте ближе к примерам.

    Возьмем маленький xml , который можно получить обратившить к любой странице в UMI.CMS, добавив .xml в конце её значения в адресной строке (например http://example.ru/test.xml)

    xml страницы http://example.ru/test/

    Затем, разберем несколько примеров вызова конструкции:

    1. Вывод значения конкретного узла. Например, название страницы из узла result/page/name . То, что мы только что написали, называется xPath выражением, которое указывает что именно нас интересует из имеющегося xml документа
    2. Вывод значения из атрибута. Например, id текущей страницы из атрибута pageId , относящегося к узлу result
    3. Вывод значения из параметра ( ) или переменной ( ), которые были обозначенны выше в данном xslt шаблоне или являются глобальными (обозначены раньше всех xslt шаблонов)
    4. Вывод значения с отключением экранирования. Например, нам надо вывести значение (value) из узла property, содержащего значение html поля «Контент» (имеет атрибут name = ‘content’)
    5. Вывод произвольного текста. Текст необходимо обрамлять дополнительными кавычками отличными от кавычек для самого значения атрибута.
    6. Вывод произвольного числа.
    7. Вывод xPath выражения, содержащего математическую функцию «(6+4) / 2». Про xPath функции можете почитать в википедии.
    Илон Маск рекомендует:  Что такое код fbsql_commit
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL