Мы уже рассмотрели XSLT-преобразования из XML в XML, HTML, XHTML, RTF, простой текст, JavaScript и даже в реляционные базы данных. В этой и следующей главах вы познакомитесь с новым преобразованием, для которого и создавались XSLT: преобразование XML в документы, которые используют форматирующие объекты, XSL (документы XSL-FO).
Такое преобразование являлось первоочередной задачей XSLT. Как вы знаете, XSLT вырос из спецификации XSL для упрощения работы с форматирующими объектами (formatting objects). Имейте в виду, что XSL-FO гораздо объемнее XSLT — здесь я смогу представить только введение в предмет.
Форматирование XSL
Как обсуждалось в главе 1, XSLT и XSL-FO составляют спецификацию XSL. В данный момент версия 1.0 этой спецификации обладает статусом рекомендации-кандидата, с последней версией вы сможете познакомиться на http://www.w3.org/TR/xsl.
Форматирующая часть XSL, XSL-FO, позволяет устанавливать точное форматирование для всего документа, вплоть до каждого миллиметра. Например, вы можете выбрать шрифт, его размер, расположение текста на странице, цвет текста, режим подчеркивания и т.д. Работа с XSL-FO во многом похожа на создание документов RTF, но с некоторыми дополнениями: например, в XSL-FO можно создавать ссылки для навигации по документам.
Если вы когда-либо видели огромное количество кодов, используемых в RTF для форматирования документов, вы поймете, что XSL-FO представляет собой сложную и очень большую спецификацию. (Вот почему появились XSLT — чтобы упростить работу с XSL-FO.) Таким образом, на отведенном месте я смогу только дать введение в эту тему. Однако пока что еще нет программ, полностью реализующих всю спецификацию, поэтому сравнительно небольшое число людей пользуются возможностями XSL-FO, выходящими за рамки материала этой и следующей глав. В следующем списке перечислен ряд доступных процессоров XSL-FO:
• fop. http://xml.apache.org/fop. Этот популярный процессор преобразует XSL- FO в PDF. Разработан Джеймсом Таубером в Apache Software Foundation (http://xml.apache.org/);
• PassiveTeX. http://users.ox.ac.uk/~rahtz/passivetex/. Этот процессор фактически представляет собой библиотеку макросов ТеХ, обеспечивающих среду для тестирования XSL-FO;
• REXP. http://www.esng.dibe.unige.it/REXP. Эта ранняя версия процессора XSL-FO. Создает файлы PDF;
• Unicorn. http://www.unicorn-enterprises.com. Этот процессор (называемый UFO) распространяется бесплатно и работает в Windows NT 4.0 и Windows 95;
• ХЕР. http://www.renderx.com/F02PDF.html. Этот процессор, обычно называемый FOP2PDF, преобразует документы XSL-FO в формат PDF;
• XSL Formatter. http://www.antennahouse.com/xslformatter.html. Процессор XSL-FO для Windows. Доступна бесплатная копия с ограниченным сроком действия (evaluation version);
Я лично предпочитаю fop, который сегодня является самым популярным процессором XSL-FO. В этой и следующей главах я буду работать с последней версией fop, 0.17. Apache Software Foundation, группа, которая создала и Xalan, осуществляет сопровождение процессора fop, преобразующего документы XSL-FO в документы в формате Portable Data Format (PDF), для просмотра которых служит Acrobat reader фирмы Adobe. Acrobat reader можно бесплатно загрузить с http://www.adobe.com/products/acrobat/readermain.html. Последнюю версию самого fop можно бесплатно загрузить с http://xml.apache.org/fop (на сегодняшний день достаточно только щелкнуть на ссылку для загрузки на этой странице).
Процессор fop работает с документами XSL-FO, и в этой и следующей главах я воспользуюсь XSLT для преобразования документов XML в формат XSL-FO и затем применю fop для преобразования документов XSL-FO в формат PDF. (Применение XSL-FO не означает, что обязательно будут создаваться документы PDF — существуют и другие форматы, — XSL-FO просто позволяет вам форматировать данные, а то, как эти форматированные данные будут представлены, зависит от используемого приложения.) Для работы с XSL-FO необходимо понимать, как работать с существующими форматирующими объектами XSL.
Форматирующие объекты XSL-FO
В документах XSLT мы работали с такими элементами, как
xlmns:xsl="http://www.w3.org/1999/XSL/Transform">
.
.
.
Документ XSL-FO написан во многом таким же способом, но вместо таких элементов XSLT, как
У форматирующих объектов есть свое собственное пространство имен, «http://www.w3.org/1999/XSL/Format», и в качестве префикса этого пространства имен практически всегда используется fo, сокращение для formatting objects. (Это соглашение было принято потому, что данный префикс пространства имен используется в спецификации XSL.) При написании документов XSL-FO используются элементы, соответствующие различным объектам XSL-FO — например,
margin-bottom="10mm" margin-top="10mm" page-width="300mm"
page-height="400mm" master-name="page">
margin-bottom="10mm" margin-top="0mm"/>
.
.
.
Обратите внимание: документы; XSL-FO являются документами XML, поэтому везде можно использовать стандартные комментарии XML, . Отметьте также, что элементы
Welcome to XSL formatting
В этом разделе мы рассмотрим объекты XSL-FO, а в следующем — свойства XSL-FO для работы с ними. При помощи объектов и свойств XSL-FO вы можете создавать документы XSL-FO, которым обычно дается расширение .fo. Процессор fop преобразует такие документы в формат .pdf.
Все форматирующие объекты XSL-FO с описанием перечислены на www.w3.org/TR/xsl/slice6.html. Во время создания книги существуют такие объекты (с работой многих из них мы познакомимся в этой и следующей главах):
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Каждый из этих элементов также поддерживает одно или несколько форматирующих свойств XSL-FO.
Форматирующие свойства XSL-FO
Форматирующие свойства XSL-FO настраивают действия перечисленных в предыдущем разделе форматирующих объектов; работайте с ними в документах XSL-FO так же, как с атрибутами элементов. Например, вот как я установил семейство (family), размер (size) и насыщенность (weight;) шрифта для текста в блоке:
font-size="36pt" font-weight="bold">
Hello from XSL-FO!
Полный список свойств XSL-FO и их описание можно найти по адресу www.w3.org/TR/xsl/slice7.html. Многие свойства XSL-FO унаследованы из спецификации для каскадных таблиц стилей версии 2, CSS2, которую вы можете найти по адресу www.w3.org/TR/REC-CSS2.
В следующем списке перечислен ряд наиболее распространенных свойств XSL-FO. Полный список свойств (весьма длинный) приведен в Приложении Б. В списке используется следующий синтаксис, соответствующий спецификации XSL-FO:
• <> обозначает единицы значений (см. таблицу 11.1) или свойства (например,
• | означает вариант выбора, использовать можно только один из них;
• || означает вариант выбора, можно использовать один или несколько вариантов в любом порядке;
• [] означает групповые инструкции, вычисляемые во многом так же, как и математические выражения;
• * означает, что предыдущий терм может встречаться ноль или более раз;
• + означает, что предыдущий терм может встречаться один или более раз;
• ? означает, что предыдущий терм необязателен;
• {} окружают пары чисел, задающие минимальное и максимальное число раз встречи терма (как в {1, 4});
Во многих свойствах XSL-FO определен определенный формат для присваиваемых им значений, как, например
Таблица 11.1. Форматы спецификации XSL-FO
Формат | Описание |
<absolute-size> | Абсолютные размеры шрифта; могут быть xx-small, x-small, small (маленький), medium (средний), large (крупный), x-large, xx-large |
<angle> | Углы; могут измеряться в deg (градусах), grad (градах) или rad (радианах) |
idctlpar<border-style> | Граница прямоугольника, может принимать значения none (нет), dotted (пунктиром), dashed (штрихами), solid (непрерывная), double (двойная), groove (канавкой), ridge (с толстой кромкой), inset (вложенная) или outset (вынесенная) |
<border-width> | Устанавливает ширину границы; может принимать значения thin (тонкая), medium (средняя), thick (толстая) или конкретного размера |
<color> | Цвет; может быть задан предопределенным значением цвета или тройным цветовым значением RGB, как в HTML, — например, «FFFFFF» для белого цвета |
<country-language> | Устанавливается в значение <language> (см. <language>) |
<family-name> | Название семейства шрифтов — такого, как Arial, Times New Roman или Courier |
<frequency> | Значения частоты; единицами измерения могут быть Hz (Гц) или KHz (кГц) |
<generic-family> | Обобщенные названия шрифтов, применяемых в качестве последней попытки, если браузер не может найти определенный шрифт. Например, serif (браузер должен выбрать шрифт serif), sans-serif (браузер должен выбрать семейство sans-serif) и monospace (браузер должен выбрать моноширинный шрифт) |
<generic-voice> | Звук голоса; может быть male (мужской), female (женский) или child (детский) |
<integer> | Стандартные целые значения |
<keep> | Контекстно-зависимое свойство; принимает значение Auto, для того чтобы не удерживать вместе ограничения, или Always для жесткого удержания ограничений вместе. Дополнительная информация приведена в спецификации XSL |
<language> | Определитель языка, соответствующий спецификации RFC1766 (которую можно найти по адресу www.w3.org/TR/xsl/sliceD.html#RFC1766) |
<length> | Длина; может начинаться с + или -, за которыми следует число. Число может содержать десятичную точку, за которой следует идентификатор единиц, принимающий значения em (размер шрифта соответствующего шрифта), ex (x-height, высота шрифта), рх (пикселов, pixel, определяется устройством просмотра), pt (пунктов, point, 1/72 дюйма), in (дюймов, inch), cm (сантиметров), mm (миллиметров) или pc (пик, pica, 1/6 дюйма) |
<length-bp-ip-direction> | Задает расстояние, разделяющее смежные границы ячейки в направлении размещения строк. Дополнительная информация приведена на www.w3.org/TR/xsl/slice7.html |
<length-conditional> | Составное значение, задающее ширину и возможный тип передней границы. Дополнительная информация приведена на www.w3.org/TR/xsl/slice7.html#pr-section |
<length-range> | Определяет диапазон длины, как определено в спецификации XSL |
<margin-width> | Может принимать значения <length>, <percentage> или auto. Работа значения auto зависит от контекста, подробности приведены на www.w3.org/TR/REC-CSS2/visudet.html#Computing_widths_and_margins |
<number> | Число, может включать знак и десятичную точку |
<padding-width> | Устанавливается в значение <length> |
<percentage> | Число, которое может содержать знак, за которым следует знак процента (%) |
<relative-size> | Размер шрифта относительно родительского элемента, может быть Larger (больше) или Smaller (меньше) |
<shape> | Пока может задавать только прямоугольник (shape — фигура), как, например: rect(<top> <right> <bottom> <left>) |
<space> | Задает минимальное, оптимальное и максимальное значения для пробела. Подробности см. на www.W3.org/TR/xsl/slice4.html#spacecond |
<specific-voice> | Задает определенный голос. Подробности см. на www.w3.org/TR/REC-CSS2/aural.html#propdef-voice-family |
<time> | Единицы времени, указанные как число, за которым сразу же следует ms (миллисекунды) или s (секунды) |
<uri-specification> | Uniform Resource Indicator (URI); web-адрес элемента страницы такого, как рисунок |
Примите также к сведению, что свойства XSL-FO, как и свойства CSS2, могут принимать значение «inherit», что означает, что значение свойства должно быть унаследовано от его родительского элемента.
В следующем списке перечислены наиболее распространенные свойства XSL-FO. Полный список приведен в Приложении Б.
• absolute-position. Определяет, является ли позиция элемента абсолютной. Устанавливается в auto | absolute | fixed | inherit;
• background. Свойство для быстрой установки сразу всех отдельных свойств заднего фона (background-color, background-image, background-repeat, background-attachment и background-position). Устанавливается в [
• background-attachment. Определяет, будет ли прокручиваться задний фон. Устанавливается в scroll | fixed | inherit;
• background-color. Задает цвет заднего фона элемента. Устанавливается в
• background-image. Задает рисунок заднего фона элемента. Устанавливается в
• background-repeat. Определяет, может ли рисунок заднего фона располагаться мозаикой, и если да, то каким образом. Устанавливается в repeat | repeat-x | repeat-y | no-repeat | inherit;
• border. Свойство для быстрой установки одинаковых ширины, цвета и стиля всех четырех границ (верхней, нижней, левой и правой) прямоугольника. Устанавливается в [
• border-after-color. Задает цвет задней границы области. Устанавливается в
• border-after-style. Задает стиль задней границы. Устанавливается в
• border-after-width. Задает ширину задней границы. Устанавливается в
• border-before-color. Задает цвет передней границы. Устанавливается в
• border-before-style. Задает стиль передней границы. Устанавливается в
• border-before-width. Задает ширину передней границы. Устанавливается в
• border-bottom. Свойство для быстрой установки ширины, стиля и цвета нижней границы области блока или встроенной области. Устанавливается в [
• border-bottom-color. Задает цвет нижней границы. Устанавливается в
• border-bottom-style. Задает стиль нижней границы. Устанавливается в
• border-bottom-width. Задает ширину нижней границы. Устанавливается в
• border-collapse. Задает модель границы таблицы. Устанавливается в collapse | separate | inherit;
• border-color. Задает цвет сразу всех четырех границ. Устанавливается в
• border-end-color. Задает цвет конечной границы. Устанавливается в
• border-end-style. Задает стиль конечной границы. Устанавливается в
• border-end-width. Задает ширину конечной границы. Устанавливается в
• border-left. Свойство для быстрой установки одновременно ширины, стиля и цвета левой границы. Устанавливается в [
• border-left-color. Задает цвет левой границы. Устанавливается в
• border-left-style. Задает стиль левой границы. Устанавливается в
• border-left-width. Задает ширину левой границы. Устанавливается в
• border-right. Свойство для быстрой установки одновременно ширины, стиля и цвета правой границы. Устанавливается в [
• border-right-color. Задает цвет правой границы. Устанавливается в
• border-right-style. Задает стиль правой границы. Устанавливается в
• border-right-width. Задает ширину правой границы. Устанавливается в
• border-spacing. Задает расстояние между смежными границами ячейки. Устанавливается в
• border-start-color. Задает цвет начальной границы. Устанавливается в
• border-start-style. Задает стиль начальной границы. Устанавливается в
• border-start-width. Задает ширину начальной границы. Устанавливается в
• border-style. Задает стиль четырех границ. Устанавливается в
• border-top. Свойство для быстрой установки одновременно ширины, стиля и цвета верхней границы области блока или встроенной области. Устанавливается в [
• border-top-color. Задает цвет верхней границы. Устанавливается в
• border-top-style. Задает стиль линии границы прямоугольника (непрерывная, двойная, штриховая и т.д.);
• border-top-width. Задает ширину верхней границы. Устанавливается в
• border-width. Свойство для быстрой установки одновременно свойств border-top-width, border-right-width, border-bottom-width и border-left-width. Устанавливается в
• bottom. Определяет, насколько нижний край содержимого прямоугольника (box) смещен вверх от нижней границы содержащего прямоугольник блока. Устанавливается в
• character. Задает вставляемый символ Unicode. Устанавливается в
• color. Задает цвет переднего фона текста элемента. Устанавливается в
• column-count. Задает число столбцов в области. Устанавливается в
• column-number. Устанавливает номер столбца для ячеек таблицы. Устанавливается в
• column-width. Задает ширину такого объекта, как внешняя графика. Устанавливается в auto | scale-to-fit |
• float. Определяет, будет ли прямоугольник прижат влево, вправо или вообще не будет прижат. Устанавливается в before | start | end | left | right | none | inherit;
• flow-name. Задает имя потока (flow). Устанавливается в
• font. Свойство для быстрого задания одновременно свойств font-style, font-variant, font-weight, font-size, line-height и font-family. Устанавливается в [ [
• font-family. Задает список имен семейств шрифтов и/или обобщенных имен семейств в порядке предпочтения. Устанавливается в [[
• font-size. Задает размер шрифта. Устанавливается в
• font-style. Задает стиль шрифта. Устанавливается в normal | italic | oblique | backslant | inherit;
• font-variant. Выбирает шрифты, имеющие строчные и прописные буквы (bicameral fonts). Устанавливается в normal | small-caps | inherit;
• font-weight. Задает насыщенность шрифта. Устанавливается в normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit;
• format. Формат XSLT. Устанавливается в
• grouping-separator. Разделитель групп разрядов формата XSLT. Устанавливается в
• grouping-size. Размер группы формата XSLT. Устанавливается в
• height. Задает высоту содержимого прямоугольников, создающихся элементами уровня блока и замещенными элементами. Устанавливается в
• initial-page-number. Задает начальный номер страницы. Устанавливается в auto | auto-odd | auto-even |
• left. Определяет, насколько левый край содержимого прямоугольника (box) смещен вправо от левой границы содержащего прямоугольник блока. Устанавливается в:
• linefeed-treatment. Определяет способ обработки символов перевода строки. Устанавливается в ignore | preserve | treat-as-space | treat-as-zero-width-space | inherit;
• line-height. Задает минимальную высоту каждого созданного встроенного прямоугольника. Устанавливается в normal |
• margin. Свойство для быстрого задания одновременно свойств полей margin-top, margin-right, margin-bottom и margin-left. Устанавливается в
• margin-bottom. Задает нижнее поле прямоугольника. Устанавливается в
• margin-left. Задает левое поле прямоугольника. Устанавливается в
• margin-right. Задает правое поле прямоугольника. Устанавливается в
• margin-top. Задает верхнее поле прямоугольника. Устанавливается в
• master-name. Задает или выбирает шаблон (master). Устанавливается в
• number-columns-spanned. Задает число столбцов, занимаемых ячейкой таблицы. Устанавливается в
• number-rows-spanned. Задает число строк, занимаемых ячейкой таблицы. Устанавливается в
• page-break-after. То же, что и свойство CSS2 с тем же именем. Устанавливается в auto | always | avoid | left | right | inherit;
• page-break-before. To же, что и свойство CSS2 с тем же именем. Устанавливается в auto | always | avoid | left | right | inherit;
• page-height. Задает высоту страницы. Устанавливается в auto | indefinite |
• page-width. Задает ширину страницы. Устанавливается в auto | indefinite |
• position. Задает используемую схему размещения. Устанавливается в static | relative | absolute | fixed | inherit;
• relative-position. То же, что и свойство CSS2 с тем же именем. Устанавливается в static | relative | inherit;
• right. Определяет, насколько край содержимого прямоугольника (box) смещен влево от правой границы содержащего прямоугольник блока. Устанавливается в
• score-spaces. Определяет, следует ли применять свойство text-decoration к пробелам. Устанавливается в true | false | inherit;
• space-treatment. Определяет способ обработки пробелов и других символов-разделителей, за исключением символов перевода строки. Устанавливается в ignore | preserve | ignore-if-before-linefeed | ignore-if-after-linefeed | ignore-if-surrounding-linefeed | inherit;
• span. Определяет, нужно ли поместить объект уровня блока в текущий столбец или растянуть его на все столбцы в области. Устанавливается в none | all | inherit;
• src. Задает ссылку URI, определяющую внешний ресурс. Устанавливается в
• start-indent. Определяет расстояние от начального края прямоугольника содержимого области, содержащей блок, до начального края прямоугольника содержимого области этого блока. Устанавливается в
• starts-row. Определяет, начинает ли эта ячейка строку. Устанавливается в true | false;
• text-align. Определяет способ выравнивания встроенного содержимого блока. Устанавливается в start | center | end | justify | inside | outside | left | right |
• text-decoration. Задает параметры оформления, добавляемого тексту элемента. Устанавливается в none | [ [ underline | no-underline] || [ overline | no-overline ] || [ line-through | no-line-through ] || [ blink | no-blink ] ] | inherit;
• text-indent. Определяет выравнивание первой строки текста в блоке. Устанавливается в
• text-shadow. Задает разделенный запятыми список теневых эффектов, которые нужно применить к тексту элемента. Устанавливается в none |
• top. Определяет, насколько край содержимого смещен ниже верхнего края содержащего его блока. Устанавливается в
• vertical-align. Определяет вертикальное расположение. Устанавливается в baseline | middle | sub | super | text-top | text-bottom [
• visibility. Определяет, будут ли отображены генерируемые элементом прямоугольники. Устанавливается в visible | hidden | collapse | inherit;
• white-space. Определяет способ обработки символов-разделителей (white-space) внутри элемента. Устанавливается в normal | pre | nowrap | inherit;
• white-space-collapse. Задает способ обработки последовательных символов-разделителей. Устанавливается в false | true | inherit;
• width. Задает ширину содержимого прямоугольников, созданных элементами уровня блока и замененными элементами. Устанавливается в
• wrap-option. Определяет наличие оболочки строк форматирующего объекта. Устанавливается в no-wrap | wrap | inherit.
Не все свойства применимы ко всем объектам XSL-FO. В этой и следующей главах я буду явно перечислять свойства, применимые к используемым мной объектам. Заметьте также, что пока что ни в одном процессоре XSL-FO не реализованы все эти свойства.
Мы вкратце рассмотрели структуру XSL-FO, теперь пора перейти к практике: сейчас мы подробно рассмотрим работу примера.
Форматирование документа XML
Чтобы посмотреть, как XSL-FO может форматировать данные XML, я воспользуюсь planets.xml (листинг 11.1).
Листинг 11.1. planets.xml
В этом первом примере я создам таблицу стилей XSLT для форматирования файла planets.xml и преобразования его в planets.fo, использующую форматирующие объекты для задания шрифтов, стилей и цветов. Затем я воспользуюсь процессором fop и преобразую planets.fo в файл planets.pdf, который показан на рис. 11.1.
Рис. 11.1. Документ PDF, созданный при помощи форматирующих объектов
Как видно на рис. 11.1, в нашем первом примере я применил средства форматирования текста: установку шрифта, подчеркивание текста, выделение текста курсивом и даже установка цвета текста. (Хотя этого и не видно на рис. 11.1, заголовок «The Planets Table» выделен светло-голубым цветом.)
Первый шаг при создании документа на рис. 11.1 — применить таблицу стилей XSLT для преобразования planets.xml в planets.fo.
Преобразование в XSL-FO при помощи таблицы стилей XSLT
В этой главе я создам таблицу стилей для преобразования planets.xml в planets.fo. Я буду создавать таблицу шаг за шагом; для справки я приведу ее окончательный вид (листинг 11.2).
Листинг 11.2. planets.xsl
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
page-height="400mm" page-width="300mm"
margin-top="10mm" margin-bottom="10mm"
margin-left="20mm" margin-right="20mm">
margin-top="0mm" margin-bottom="10mm"
margin-left="0mm" margin-right="0mm"/>
line-height="48pt" font-family="Times" color="blue">
The Planets Table
line-height="48pt" font-family="Times"
font-style="italic">
Planet:
font-family="Times">
Mass
:
[Earth = 1]
font-family="Times">
Day
:
[Earth = 1]
font-family="Times">
Radius
:
miles
font-family="Times">
Density
:
[Earth = 1]
font-family="Times">
Distance
:
million miles
После применения этой таблицы стилей для преобразования planets.xsl будет получен файл planets.fo, который при помощи форматирующих объектов XSL-FO создает документ с видом, показанным на рис. 11.1. Вот как выглядит planets.fo (листинг 11.3).
Листинг 11.3. planets.fo
margin-left="20mm" margin-bottom="10mm"
margin-top="10mm" page-width="300mm"
page-height="400mm" master-name="page">
margin-bottom="10mm" margin-top="0mm"/>
line-height="48pt" font-size="36pt" font-weight="bold">
The Planets Table
line-height="48pt" font-size="28pt" font-weight="bold">
Planet:
Mercury
Mass
:
.0553
[Earth = 1]
Day
:
58.65
[Earth = 1]
Radius
:
1516
miles
Density
:
.983
[Earth = 1]
Distance
:
43.4
million miles
font-size="28pt" font-weight="bold">
Planet:
Venus
Mass
:
.815
[Earth = 1]
Day
:
116.75
[Earth = 1]
Radius
:
3716
miles
Density
:
.943
[Earth = 1]
Distance
:
66.8
million miles
font-size="28pt" font-weight="bold">
Planet:
Earth
Mass
:
1
[Earth = 1]
Day
:
1
[Earth = 1]
Radius
:
2107
miles
Density
:
1
[Earth = 1]
Distance
:
128.4
million miles
Для того чтобы обработать planets.fo и создать форматированный документ, я воспользуюсь процессором fop от Apache XML Project. Как утверждает Apache: «FOP — первое в мире средство форматирования, управляемое форматирующими объектами XSL. Приложение Java считывает дерево форматирующих объектов и затем преобразует его в документ PDF. Дерево форматирующих объектов может быть представлено в форме документа XML (полученного на выходе такого процессора XSLT, как XT или Xalan) или может быть передано в память как документ DOM или (в случае XT) событий SAX».
Я пользуюсь fop 0.17, — последней версией процессора на момент написания книги (похоже, что новые версии выходят практически ежемесячно). Процессор fop можно бесплатно загрузить с http://xml.apache.org/fop. Пакет загрузки fop включает три необходимых для работы файла JAR: fop.jar, w3c.jar и xerces.jar, которые нужно включить в classpath (добавьте правильные пути к этим файлам JAR в соответствии с требованиями вашей системы):
С:\>set classpath=.;fop.jar;xerces.jar;w3c.jar
Для преобразования planets.fo в planets.pdf служит класс fop org.apache.fop.apps.CommandLine, которому в командной строке нужно передать имя входного документа, planets.fo, и имя выходного, planets.pdf:
C:\>java org.apache.fop.apps.CommandLine planets.fo planets.pdf
Вот и все; окончательный результат, planets.pdf, в средстве просмотра Adobe Acrobat Reader вы увидите, если вернетесь к рис. 11.1.
Теперь вы видели, как выполняется процедура в общем; давайте перейдем к деталям и посмотрим, как создаются документы XSL-FO. Чтобы подробно все рассмотреть, я собираюсь взять за основу листинг 11.2, таблицу стилей XSLT, создающую planets.fo.
СОЗДАНИЕ ДОКУМЕНТОВ XSL-FO С НУЛЯ
Заметьте, что не обязательно создавать таблицу стилей для преобразования документов XSL в форму XSL-FO. Я мог бы написать planets.fo так, как показано в листинге 11.3, с нуля, не прибегая к таблицам стилей XSLT. Но такой способ, как правило, годится только для коротких документов XML. Документы с форматированием XSL-FO становятся весьма длинными очень быстро (сравните длину planets.xml с planets.fo), поэтому для создания документов XSL-FO практически всегда применяйте таблицы стилей XSLT (хотя некоторые примеры в следующей главе достаточно коротки для того, чтобы написать их непосредственно при помощи XSL-FO).
Создание корня документа: <fo:root>
Первый форматирующий документ, который мы рассмотрим, — это
Детьми форматирующего объекта
На первом шаге в таблице стилей XSLT, преобразующей planets.xml, я выбираю узел документа
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
.
.
.
Элемент
Создание схемы набора шаблонов: <fo:layout-master-set>
Шаблоны (master) могут быть определены для страниц, последовательностей страниц и областей. Элемент
Шаблоны страниц формируют отдельные страницы, шаблоны последовательностей страниц — последовательности страниц; шаблоны областей позволяют форматировать определенные области страницы. В следующем примере я создам единственный шаблон при помощи
Шаблоны, которые вы хотите применить в документе, должны быть перечислены в элементе
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
.
.
.
.
.
.
Этот элемент содержит шаблон страницы, как определено в элементе
Создание шаблона страницы: <fo:simple-page-master>
Как можно догадаться из названия, шаблон страницы (page master) применяется для создания страницы. Шаблон страницы задает фактическую схему и конфигурацию страницы. Каждому шаблону страницы должно быть задано уникальное имя, к которому и нужно обращаться при работе с шаблоном.
В настоящей спецификации XSL существует единственный вид шаблона страницы,
• общие свойства полей для блоков: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;
• master-name;
• page-height;
• page-width;
• reference-orientation;
• writing-mode.
В таблице стилей XSLT, которую я применил к planets.xml, я задал простому шаблону страницы имя «page» при помощи свойства master-name. После этого шаблон стал именованным, и когда мне нужно создать страницы по этому шаблону, я обращаюсь к нему по этому имени. Я также задаю размеры и поля страницы при помощи свойств страницы и полей следующим образом:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
page-height="400mm" page-width="300mm"
margin-top="10mm" margin-bottom="10mm"
margin-left="20mm" margin-right="20mm">
.
.
.
В дополнение к заданию схемы расположения полей страницы, у
Создание областей
В версии 1.0 спецификации XSL у шаблонов страниц имелось пять областей (region). Центральная область, соответствующая основной части, телу страницы, называется областью тела (body region). Верхняя часть страницы, верхний колонтитул (header), называется передней областью (before region); нижняя часть страницы, нижний колонтитул (footer), называется задней областью (after region). В языках, которые читаются слева направо, как английский язык, левая часть страницы называется начальной областью (start region), а правая часть называется конечной областью (end region). В языках, которые читаются справа налево, начальная и конечная области меняются местами. Начальная и конечная области аналогичны боковым полям, расположенным по бокам области тела.
Этим областям соответствуют следующие элементы XSL-FO:
•
•
•
•
•
С ними можно применять следующие свойства:
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• общие свойства полей для блоков: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;
• clip;
• column-count;
• column-gap;
• display-align;
• extent;
• overflow;
• region-name;
• reference-orientation;
• writing-mode.
Области страницы можно настраивать по вашему желанию, как в таблице стилей XSLT, в которой я задал поля для области тела. Четыре внешних области (но не область тела) имеют свойство extent, задающее их размер, которым я здесь воспользуюсь:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
page-height="400mm" page-width="300mm"
margin-top="10mm" margin-bottom="10mm"
margin-left="20mm" margin-right="20mm">
margin-left="0mm" margin-right="0mm"/>
.
.
.
Это завершает используемый в документе шаблон, простой шаблон страницы «page», почему здесь также завершается и элемент
В дополнение к элементу
Создание последовательностей страниц: <fo:page-sequence>
Что такое последовательность страниц? Это ряд страниц с одинаковыми характеристиками (например, глава в книге), которые при желании можно форматировать одинаковым способом. Страницы в результирующем документе в действительности создаются тогда, когда процессор XSL-FO обрабатывает элементы
Каждый элемент
К объекту
• country;
• format;
• language;
• letter-value;
• grouping-separator;
• grouping-size;
• id;
• initial-page-number;
• force-page-count;
• master-name.
В последней рекомендации XSL W3C шаблон страницы для последовательности страниц задается атрибутом master-name элемента
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
page-height="400mm" page-width="300mm"
margin-top="10mm" margin-bottom="10mm"
margin-left="20mm" margin-right="20mm">
margin-left="0mm" margin-right="0mm"/>
.
.
.
.
.
.
Этот код определяет шаблон страницы, который будет использован для последовательности страниц. Теперь мне нужно задать содержимое (content) последовательности, что делается при помощи детей потока (flow) элемента
Создание объектов потока: <fo:flows>
Объекты потока носят такое название потому, что текст в них «заливается» и выравнивается, заполняя страницу, программой, отвечающей за вывод на экран. Содержимое страницы управляется объектами потока.
Есть два вида объектов потока:
К
• flow-name.
Я воспользуюсь элементом
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
.
.
.
.
.
.
Здесь мы заканчиваем рассмотрение элемента
Создание содержимого уровня блока: <fo:block>
Блоки играют важную роль в XSL-FO: они применяются для создания прямоугольных областей вывода, отделенных от других областей вывода в документе. Форматирующий объект
Welcome to XSL formatting.
С объектом
• общие свойства доступа: source-document, role;
• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position- horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• общие свойства шрифта: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight;
• общие свойства переноса: country, language, script, hyphenate, hyphenation-character, hyphenation-push-character-count, hyphenation-remain-character-count;
• общие свойства полей для блоков: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;
• break-after;
• break-before;
• color;
• font-height-override-after;
• font-height-override-before;
• hyphenation-keep;
• hyphenation-ladder-count;
• id;
• keep-together;
• keep-with-next;
• keep-with-previous;
• last-line-end-indent;
• linefeed-treatment;
• line-height;
• line-height-shift-adjustment;
• line-stacking-strategy;
• orphans;
• relative-position;
• space-treatment;
• span;
• text-align;
• text-align-last;
• text-indent;
• visibility;
• white-space-collapse;
• widows;
• wrap-option;
• z-index.
Например, я могу добавить в документ заголовок «The Planets Table» (Таблица планет), задав шрифт Times (в данный момент fop поставляется с встроенными шрифтами Times, Helvetica, Courier, Symbol, sans-serif, serif и ZapfDingbats) в свойстве font-family, размер шрифта 36 пунктов в свойстве font-size и полужирный стиль, установив свойство font-weight в «bold». Высоту блока я задам при помощи свойства line-height и покажу заголовок голубым при помощи свойства color:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
.
.
.
line-height="48pt" font-family="Times" color="blue">
The Planets Table
.
.
.
Этот код создаст блок заголовка, который показан в верхней части текста на рис. 11.1. Таким способом я могу создать аналогичные блоки для каждого элемента данных каждой планеты при помощи таблицы стилей XSLT. Заметьте также, что я вывожу имя каждой планеты курсивом, установив свойство font-style в «italic», и я подчеркиваю остальной текст при помощи свойства text-decoration элементов
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
.
.
.
.
.
.
line-height="48pt" font-family="Times" font-style="italiс">
Planet:
Mass
:
[Earth = 1]
.
.
.
Вот и все. Вы создали свое первое преобразование из XML в XSL-FO, преобразовав planets.xml в planets.fo. Процессор fop создаст из planets.fo файл planets.pdf, и вы можете вернуться к рис. 11.1 и посмотреть на результат.
Это преобразование форматировало данные в planets.xml и отображало их в блоках, одно за другим. С другой стороны, в предыдущих главах мы видели данные планет в виде таблицы. Можно ли это сделать в XSL-FO? Никаких проблем.
Создание таблиц
Таблица — одна из самых полезных структур, которые можно форматировать при помощи XSL-FO. Таблица в XSL-FO во многом похожа на таблицу в HTML: это прямоугольная сетка, состоящая из строк и столбцов ячеек. Для создания таблиц можно применять девять форматирующих элементов.
•
•
•
•
•
•
•
•
•
Создание таблиц в XSL-FO аналогично их созданию в HTML. Вы создаете элемент
Следующий пример (листинг 11.4) демонстрирует работу с этими элементами. Приведенная таблица стилей XSLT преобразует planets.xml в документ XSL-FO, форматирующий данные планет в таблицу XSL-FO.
Листинг 11.4. tables.xsl
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
page-height="400mm" page-width="300mm"
margin-top="10mm" margin-bottom="10mm"
margin-left="20mm" margin-right="20mm">
margin-left="0mm" margin-right="0mm"/>
Name
Mass
Day
Radius
Density
Distance
Вот результат после преобразования в документ XSL-FO (листинг 11.5).
Листинг 11.5. tables.fo
margin-bottom="10mm" margin-top="10mm" page-width="300mm"
page-height="400mm" master-name="page">
margin-bottom="10mm" margin-top="0mm"/>
Name
Mass
Day
Radius
Density
Distance
После обработки этого документа, tables.fo, процессором fop будет создан файл tables.pdf, который показан на рис. 11.2. Вот как выглядит таблица XSL-FO, хотя существует также весьма много других параметров — например, можно задать цвет заднего фона ячеек при помощи свойства background-color. По умолчанию в таких таблицах отсутствуют границы, но я добавил границу толщиной в 0,5 мм при помощи свойства border-width. Заметьте также, что для того, чтобы установить размер шрифта для текста в каждой ячейке, я использую блок внутри каждой ячейки таблицы:
Рис. 11.2. Таблица, отформатированная при помощи XSL-FO, в Adobe Acrobat Reader
Давайте рассмотрим различные элементы, нужные для создания таблицы, и начнем мы с большого элемента,
Создание таблиц: <fo:table>
Как можно догадаться из названия, элемент
С элементом
• общие свойства доступа: source-document, role;
• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;
• общие свойства границ (border), заполнения (padding) и заднего фона (background): background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• общие свойства полей: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent;
• block-progression-dimension;
• border-collapse;
• border-separation;
• break-after;
• break-before;
• id;
• inline-progression-dimension;
• height;
• keep-together;
• keep-with-next;
• keep-with-previous;
• relative-position;
• table-layout;
• table-omit-footer-at-break;
• table-omit-header-at-break;
• width;
• writing-mode;
Как видно из листинга 11.5, таблица tables.fo начинается с
.
.
.
Следующий шаг в создании таблицы — задать столбцы таблицы при помощи
Создание столбцов таблицы: <fo:table-column>
Для каждого столбца в таблице нужно включить один элемент
С элементом
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• column-number;
• column-width;
• number-columns-repeated;
• number-columns-spanned;
• visibility.
В tables.fo я установил для каждого столбца одинаковую ширину, 30 мм:
.
.
.
После задания каждого столбца создается тело таблицы.
Создание тел таблицы: <fo:table-body>
Тело таблицы (table body) содержит фактическое содержимое таблицы; тела создаются при помощи элемента
С элементом
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• id;
• relative-position.
Как можно видеть в листинге 11.5, для создания тела таблицы в tables.fo я использовал
.
.
.
После создания тела таблицы нужно создать строки таблицы при помощи элемента
Создание строк таблицы: <fo:table-row>
Аналогично таблицам HTML, для создания строк таблицы применяется элемент
С элементом
• общие свойства доступа: source-document, role;
• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• block-progression-dimension;
• break-after;
• break-before;
• id;
• height;
• keep-together;
• keep-with-next;
• keep-with-previous;
• relative-position.
Я добавил строки в таблицу в tables.fo при помощи элементов
.
.
.
.
.
.
Создав нужные строки, мы теперь готовы к включению в ячейки таблицы самих данных.
Создание ячеек таблицы: <fo:table-cell>
Снова, почти как при создании таблицы в HTML, вы помещаете данные в отдельные ячейки таблицы при помощи элемента
С элементом
• общие свойства доступа: source-document, role;
• общие звуковые свойства: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume;
• общие свойства границ, заполнения и заднего фона: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right;
• block-progression-dimension;
• column-number;
• display-align;
• relative-align;
• empty-cells;
• ends-row;
• height;
• id;
• number-columns-spanned;
• number-rows-spanned;
• relative-position;
• starts-row;
• width.
В tables.fo я поместил в ячейки таблицы и подписи к каждому столбцу, и данные таблицы следующим образом:
Name
Mass
Day
Radius
Density
Distance
Mercury
.0553
58.65
1516
.983
43.4
.
.
.
Теперь все готово — результат показан на рис. 11.2, где вы можете увидеть полностью отформатированную таблицу, созданную процессором fop. Теперь вы знаете, как создавать таблицы при помощи форматирующих объектов XSL.
Безусловно, можно еще много сказать о XSL-FO. В следующей главе мы рассмотрим работу со списками, размещение, колонки, последовательности страниц и другие элементы.