• Форматирование XSL
  • Форматирующие объекты XSL-FO
  • Форматирующие свойства XSL-FO
  • Форматирование документа XML
  • Преобразование в XSL-FO при помощи таблицы стилей XSLT
  • Создание корня документа: <fo:root>
  • Создание схемы набора шаблонов: <fo:layout-master-set>
  • Создание шаблона страницы: <fo:simple-page-master>
  • Создание областей
  • Создание последовательностей страниц: <fo:page-sequence>
  • Создание объектов потока: <fo:flows>
  • Создание содержимого уровня блока: <fo:block>
  • Создание таблиц
  • Создание таблиц: <fo:table>
  • Создание столбцов таблицы: <fo:table-column>
  • Создание тел таблицы: <fo:table-body>
  • Создание строк таблицы: <fo:table-row>
  • Создание ячеек таблицы: <fo:table-cell>
  • Глава 11

    Применение XSLT для создания документов XSL-FO

    Мы уже рассмотрели 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 мы работали с такими элементами, как

    <xsl:stylesheet>
    ,
    <xsl:output>
    и т.д.:

    <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet version="1.0"

     xlmns:xsl="http://www.w3.org/1999/XSL/Transform">

     <xsl:output method="xml"/>

     <xsl:template match="*">

      <xsl:copy>

       <xsl:apply-templates/>

        .

        .

        .

    Документ XSL-FO написан во многом таким же способом, но вместо таких элементов XSLT, как

    <xsl:stylesheet>
    , применяются элементы, основанные на форматирующих объектах XSL-FO. Существует всего 56 таких форматирующих объектов — например, объект корня, создающий корневой узел документа XSL-FO, или объект блока, создающий область блока (прямоугольную область отображения, похожую на область, которую тег заголовка <Н1> создает в документе HTML).

    У форматирующих объектов есть свое собственное пространство имен, «http://www.w3.org/1999/XSL/Format», и в качестве префикса этого пространства имен практически всегда используется fo, сокращение для formatting objects. (Это соглашение было принято потому, что данный префикс пространства имен используется в спецификации XSL.) При написании документов XSL-FO используются элементы, соответствующие различным объектам XSL-FO — например,

    <fo:root>
    для корневого элемента,
    <fo:block>
    для создания блока отображения и т.д. Вот как можно начать документ XSL-FO — заметьте, что я объявляю префикс пространства имен «
    fo
    », соответствующий пространству имен XSL-FO:

    <?xml version="1.0" encoding="UTF-8"?>

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

     <fо:layout-master-set>

      <fo:simple-page-master margin-right="20mm" margin-left="20mm"

       margin-bottom="10mm" margin-top="10mm" page-width="300mm"

       page-height="400mm" master-name="page">

       <fo:region-body margin-right="0mm" margin-left="0mm"

        margin-bottom="10mm" margin-top="0mm"/>

       .

       .

       .

    Обратите внимание: документы; XSL-FO являются документами XML, поэтому везде можно использовать стандартные комментарии XML,

    <!-- такие как этот -->
    . Отметьте также, что элементы
    <fo:simple-page-master>
    и
    <fo:region-body>
    обладают такими атрибутами, как
    margin-right
    и
    page-height
    . В XSL-FO такие атрибуты называются свойствами, и их весьма много — на момент написания книги около 240. Например, вот как можно создать блок XSL-FO — прямоугольную область отображения — в котором выводится текст «Welcome to XSL formatting» (Добро пожаловать в форматирование XSL) шрифтом
    sans-serif
    размером 36 пунктов. Я использую форматирующий объект
    <fo:block>
    и свойства XSL-FO
    font-family
    line-height
    (задающее высоту блока) и
    font-size
    :

    <fo:block font-family="sans-serif" line-height="48pt" font-size="36pt">

     Welcome to XSL formatting

    </fo:block>

    В этом разделе мы рассмотрим объекты XSL-FO, а в следующем — свойства XSL-FO для работы с ними. При помощи объектов и свойств XSL-FO вы можете создавать документы XSL-FO, которым обычно дается расширение

    .fo
    . Процессор fop преобразует такие документы в формат
    .pdf
    .

    Все форматирующие объекты XSL-FO с описанием перечислены на www.w3.org/TR/xsl/slice6.html. Во время создания книги существуют такие объекты (с работой многих из них мы познакомимся в этой и следующей главах):

    • 

    <fo:bidi-override>
    . Перекрывает двунаправленный алгоритм Unicode (этот алгоритм используется в документах на нескольких языках);

    • 

    <fo:block>
    . Создает блок отображения для формирования прямоугольных областей, используемых при выводе абзацев, заголовков, подписей к рисункам и таблицам и т.д.;

    • 

    <fo:block-container>
    . Создает контейнер блоков, который затем можно помещать в любом месте;

    • 

    <fo:character>
    . Представляет единственный символ;

    • 

    <fo:color-profile>
    . Создает цветовой профиль для таблицы стилей, с которым потом можно работать при помощи цветовых функций (подробности см. на www.w3.org/TR/xsl/slice5.html#expr-color-functions);

    • 

    <fo:conditional-page-master-reference>
    . Задает шаблон страницы (page-master), который следует использовать при выполнении указанных условий;

    • 

    <fo:declarations>
    . Создает глобальные объявления;

    • 

    <fo:external-graphic>
    . Добавляет в документ графику (графические данные располагаются за пределами результирующего документа, но могут быть интегрированы в документы PDF такими процессорами, как fop);

    • 

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

    • 

    <fo:flow>
    . Обрабатывает поток текста, отображаемый в документе. Накладывает блокировку на «поток» встроенных областей, когда они заменяются в документе;

    • 

    <fo:footnote>
    . Задает ссылку на сноску, а также саму связанную с ней сноску;

    • 

    <fo:footnote-body>
    . Определяет содержимое сноски;

    • 

    <fo:initial-property-set>
    . Задает форматирующие свойства для начальной строки блока;

    • 

    <fo:inline>
    . Создает встроенную область (inline area). Встроенные области часто применяются для форматирования определенной части текста в блоке;

    • 

    <fo:inline-container>
    . Создает контейнер для встроенных объектов, позволяя обрабатывать их все вместе;

    • 

    <fo:instream-foreign-object>
    . Используется для вставки в документ встроенной графики или другого объекта;

    • 

    <fo:layout-master-set>
    . Задает оболочку для всех шаблонов, используемых в документе;

    • 

    <fo:leader>
    . Создает строку из повторяющегося символа или образец из символов для разделения двух текстовых форматирующих объектов;

    • 

    <fo:list-block>
    . Создает форматированный список, — с ним мы познакомимся в следующей главе;

    • 

    <fo:list-item>
    . Задает метку и тело элемента списка;

    • 

    <fo:list-item-body>
    . Задает содержимое тела элемента списка;

    • 

    <fo:list-item-label>
    . Задает содержимое метки элемента списка;

    • 

    <fo:marker>
    . Применяется вместе с <fo:retrieve-marker> для создания колонтитулов или сносок по ходу работы;

    • 

    <fo:multi-case>
    . Задает объекты, которые показывает или скрывает родительский элемент
    <fo:multi-switch>
    ;

    • 

    <fo:multi-properties>
    . Позволяет переключаться между двумя или более наборами свойств;

    • 

    <fo:multi-property-set>
    . Задает альтернативный набор свойств;

    • 

    <fo:multi-switch>
    . Переключает между двумя или более поддеревьями форматирующих объектов;

    • 

    <fo:multi-toggle>
    . Используется внутри элемента
    <fo:multi-case>
    для переключения на другой
    <fo:multi-case>
    ;

    • 

    <fo:page-number>
    . Указывает номер текущей страницы;

    • 

    <fo:page-number-citation>
    . Ссылается на номер страницы, содержащей заданный форматирующий объект;

    • 

    <fo:page-sequence>
    . Определяет способ создания последовательности страниц в документе;

    • 

    <fo:page-sequence-master>
    . Содержит последовательности шаблонов страниц, используемых для создания последовательностей страниц;

    • 

    <fo:region-after>
    . Обозначает область, расположенную после области
    <fo:region-body>
    ;

    • 

    <fo:region-before>
    . Обозначает область перед областью
    <fo:region-body>
    ;

    • 

    <fo:region-body>
    . Обозначает область в центре
    <fo:simple-page-master>
    ;

    • 

    <fo:region-end>
    . Обозначает область в конце области
    <fo:region-body>
    ;

    • 

    <fo:region-start>
    . Обозначает область, начинающую область
    <fo:region-body>
    ;

    • 

    <fo:repeatable-page-master-alternatives>
    . Задает повторяющиеся экземпляры набора альтернативных шаблонов страниц;

    • 

    <fo:repeatable-page-master-reference>
    . Обозначает подпоследовательность повторяющихся экземпляров единственного шаблона страницы;

    • 

    <fo:retrieve-marker>
    . Используется вместе с
    <fo:marker>
    для создания колонтитулов или сносок в рабочем режиме;

    • 

    <fo:root>
    . Узел документа, отформатированного при помощи XSL;

    • 

    <fo:simple-link>
    . Задает начальное место в простой ссылке;

    • 

    <fo:simple-page-master>
    . Определяет форму страницы, которая может быть разделена на области (до пяти областей);

    • 

    <fo:single-page-master-reference>
    . Определяет подпоследовательность, образованную из единственного экземпляра единственного шаблона страницы;

    • 

    <fo:static-content>
    . Содержит последовательность форматирующих объектов, которые будут отображены в одной области или повторены в областях в одной или более страницах в последовательности страниц. Чаще всего применяется для повторяющихся колонтитулов и сносок;

    • 

    <fo:table>
    . Создает таблицу. Содержит такие элементы, как
    <fo:table-column>
    и
    <fo:table-body>
    ;

    • 

    <fo:table-and-caption>
    . Содержит данные и заголовок таблицы;

    • 

    <fo:table-body>
    . Определяет содержимое тела таблицы. Содержит такие элементы, как
    <fo:table-row>
    ;

    • 

    <fo:table-caption>
    . Задает форматирующие объекты уровня блока, в которых содержится заголовок таблицы;

    • 

    <fo:table-cell>
    . Помещает данные в ячейки таблицы;

    • 

    <fo:table-column>
    . Задает свойства ячеек в одном столбце таблицы;

    • 

    <fo:table-footer>
    . Определяет содержимое нижнего колонтитула таблицы;

    • 

    <fo:table-header>
    . Определяет содержимое верхнего колонтитула таблицы;

    • 

    <fo:table-row>
    . Связывает ячейки таблицы в строки. Содержит элементы
    <fo:table-cell>
    ;

    • 

    <fo:title>
    . Задает заголовок документа;

    • 

    <fo:wrapper>
    . Задает свойства для группы форматирующих объектов;

    Каждый из этих элементов также поддерживает одно или несколько форматирующих свойств XSL-FO.

    Форматирующие свойства XSL-FO

    Форматирующие свойства XSL-FO настраивают действия перечисленных в предыдущем разделе форматирующих объектов; работайте с ними в документах XSL-FO так же, как с атрибутами элементов. Например, вот как я установил семейство (family), размер (size) и насыщенность (weight;) шрифта для текста в блоке:

    <fo:block color="blue" font-family="Times"

     font-size="36pt" font-weight="bold">

     Hello from XSL-FO!

    </fo:block>

    Полный список свойств 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) или свойства (например, <color>), которые уже были определены;

    • 

    |
    означает вариант выбора, использовать можно только один из них;

    • 

    ||
    означает вариант выбора, можно использовать один или несколько вариантов в любом порядке;

    • 

    []
    означает групповые инструкции, вычисляемые во многом так же, как и математические выражения;

    • 

    *
    означает, что предыдущий терм может встречаться ноль или более раз;

    • 

    +
    означает, что предыдущий терм может встречаться один или более раз;

    • 

    ?
    означает, что предыдущий терм необязателен;

    • 

    {}
    окружают пары чисел, задающие минимальное и максимальное число раз встречи терма (как в {1, 4});

    Во многих свойствах XSL-FO определен определенный формат для присваиваемых им значений, как, например

    <color>
    или
    <angle>
    , — эти форматы и их описание перечислены в табл. 11.1.


    Таблица 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-color> || <background-image> || <background-repeat> || <background-attachment> || <background-position> ] | inherit
    ;

    • 

    background-attachment
    . Определяет, будет ли прокручиваться задний фон. Устанавливается в
    scroll | fixed | inherit
    ;

    • 

    background-color
    . Задает цвет заднего фона элемента. Устанавливается в
    <color> | transparent | inherit
    ;

    • 

    background-image
    . Задает рисунок заднего фона элемента. Устанавливается в
    <uri-specification> | none | inherit
    ;

    • 

    background-repeat
    . Определяет, может ли рисунок заднего фона располагаться мозаикой, и если да, то каким образом. Устанавливается в
    repeat | repeat-x | repeat-y | no-repeat | inherit
    ;

    • 

    border
    . Свойство для быстрой установки одинаковых ширины, цвета и стиля всех четырех границ (верхней, нижней, левой и правой) прямоугольника. Устанавливается в
    [ <border-width> || <border-style> || <color> ] | inherit
    ;

    • 

    border-after-color
    . Задает цвет задней границы области. Устанавливается в
    <color> | inherit
    ;

    • 

    border-after-style
    . Задает стиль задней границы. Устанавливается в
    <border- style> | inherit
    ;

    • 

    border-after-width
    . Задает ширину задней границы. Устанавливается в
    <border-width> | <length-conditional> | inherit
    ;

    • 

    border-before-color
    . Задает цвет передней границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-before-style
    . Задает стиль передней границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-before-width
    . Задает ширину передней границы. Устанавливается в
    <border-width> | <length-conditional> | inherit
    ;

    • 

    border-bottom
    . Свойство для быстрой установки ширины, стиля и цвета нижней границы области блока или встроенной области. Устанавливается в
    [ <border-top-width> || <border-style> || <color> ] | inherit
    ;

    • 

    border-bottom-color
    . Задает цвет нижней границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-bottom-style
    . Задает стиль нижней границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-bottom-width
    . Задает ширину нижней границы. Устанавливается в
    <border-width> | inherit
    ;

    • 

    border-collapse
    . Задает модель границы таблицы. Устанавливается в
    collapse | separate | inherit
    ;

    • 

    border-color
    . Задает цвет сразу всех четырех границ. Устанавливается в
    <color>{1,4} | transparent | inherit
    ;

    • 

    border-end-color
    . Задает цвет конечной границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-end-style
    . Задает стиль конечной границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-end-width
    . Задает ширину конечной границы. Устанавливается в
    <border-width> | <length-conditional> | inherit
    ;

    • 

    border-left
    . Свойство для быстрой установки одновременно ширины, стиля и цвета левой границы. Устанавливается в
    [ <border-top-width> || <border-style> || <color> ] | inherit
    ;

    • 

    border-left-color
    . Задает цвет левой границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-left-style
    . Задает стиль левой границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-left-width
    . Задает ширину левой границы. Устанавливается в
    <border-width> | inherit
    ;

    • 

    border-right
    . Свойство для быстрой установки одновременно ширины, стиля и цвета правой границы. Устанавливается в
    [ <border-top-width> || <border-style> || <color> ] | inherit
    ;

    • 

    border-right-color
    . Задает цвет правой границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-right-style
    . Задает стиль правой границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-right-width
    . Задает ширину правой границы. Устанавливается в
    <border-width> | inherit
    ;

    • 

    border-spacing
    . Задает расстояние между смежными границами ячейки. Устанавливается в
    <length> <length>? | inherit
    ;

    • 

    border-start-color
    . Задает цвет начальной границы. Устанавливается в
    <color>
    ;

    • 

    border-start-style
    . Задает стиль начальной границы. Устанавливается в
    <border-style> | inherit
    ;

    • 

    border-start-width
    . Задает ширину начальной границы. Устанавливается в
    <border-width> | <length-conditional> | inherit
    ;

    • 

    border-style
    . Задает стиль четырех границ. Устанавливается в
    <border-style> {1,4} | inherit
    ;

    • 

    border-top
    . Свойство для быстрой установки одновременно ширины, стиля и цвета верхней границы области блока или встроенной области. Устанавливается в
    [ <border-top-width> || <border-style> || <color> ] | inherit
    ;

    • 

    border-top-color
    . Задает цвет верхней границы. Устанавливается в
    <color> | inherit
    ;

    • 

    border-top-style
    . Задает стиль линии границы прямоугольника (непрерывная, двойная, штриховая и т.д.);

    • 

    border-top-width
    . Задает ширину верхней границы. Устанавливается в
    <border-width> | inherit
    ;

    • 

    border-width
    . Свойство для быстрой установки одновременно свойств
    border-top-width
    ,
    border-right-width
    ,
    border-bottom-width
    и
    border-left-width
    . Устанавливается в
    <border-width>{1,4} | inherit
    ;

    • 

    bottom
    . Определяет, насколько нижний край содержимого прямоугольника (box) смещен вверх от нижней границы содержащего прямоугольник блока. Устанавливается в
    <length> | <percentage> | auto | inherit
    ;

    • 

    character
    . Задает вставляемый символ Unicode. Устанавливается в
    <character>
    ;

    • 

    color
    . Задает цвет переднего фона текста элемента. Устанавливается в
    <color> | inherit
    ;

    • 

    column-count
    . Задает число столбцов в области. Устанавливается в
    <number> | inherit
    ;

    • 

    column-number
    . Устанавливает номер столбца для ячеек таблицы. Устанавливается в
    <number>
    ;

    • 

    column-width
    . Задает ширину такого объекта, как внешняя графика. Устанавливается в
    auto | scale-to-fit | <length> | <percentage> | inherit
    ;

    • 

    float
    . Определяет, будет ли прямоугольник прижат влево, вправо или вообще не будет прижат. Устанавливается в
    before | start | end | left | right | none | inherit
    ;

    • 

    flow-name
    . Задает имя потока (flow). Устанавливается в
    <name>
    ;

    • 

    font
    . Свойство для быстрого задания одновременно свойств
    font-style
    ,
    font-variant
    ,
    font-weight
    ,
    font-size
    ,
    line-height
    и
    font-family
    . Устанавливается в
    [ [ <font-style> || <font-variant> || <font-weight> ]? <font-size> [ / <line-height>]? <font- family> ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
    ;

    • 

    font-family
    . Задает список имен семейств шрифтов и/или обобщенных имен семейств в порядке предпочтения. Устанавливается в
    [[ <family-name> | <generic-family> ],]* <family-name> | <generic-family>] | inherit
    ;

    • 

    font-size
    . Задает размер шрифта. Устанавливается в
    <absolute-size> | <relative-size> | <length> | <percentage> | inherit
    ;

    • 

    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. Устанавливается в
    <string>
    ;

    • 

    grouping-separator
    . Разделитель групп разрядов формата XSLT. Устанавливается в
    <character>
    ;

    • 

    grouping-size
    . Размер группы формата XSLT. Устанавливается в
    <number>
    ;

    • 

    height
    . Задает высоту содержимого прямоугольников, создающихся элементами уровня блока и замещенными элементами. Устанавливается в
    <length>
    |
    <percentage>
    |
    auto
    |
    inherit
    ;

    • 

    initial-page-number
    . Задает начальный номер страницы. Устанавливается в
    auto | auto-odd | auto-even | <number> | inherit
    ;

    • 

    left
    . Определяет, насколько левый край содержимого прямоугольника (box) смещен вправо от левой границы содержащего прямоугольник блока. Устанавливается в:
    <length> | <percentage> | auto | inherit
    ;

    • 

    linefeed-treatment
    . Определяет способ обработки символов перевода строки. Устанавливается в
    ignore | preserve | treat-as-space | treat-as-zero-width-space | inherit
    ;

    • 

    line-height
    . Задает минимальную высоту каждого созданного встроенного прямоугольника. Устанавливается в
    normal | <length> | <number> | <percentage> | <space> | inherit
    ;

    • 

    margin
    . Свойство для быстрого задания одновременно свойств полей
    margin-top
    ,
    margin-right
    ,
    margin-bottom
    и
    margin-left
    . Устанавливается в
    <margin-width> {1,4} | inherit
    ;

    • 

    margin-bottom
    . Задает нижнее поле прямоугольника. Устанавливается в
    <margin-width> | inherit
    ;

    • 

    margin-left
    . Задает левое поле прямоугольника. Устанавливается в
    <margin-width> | inherit
    ;

    • 

    margin-right
    . Задает правое поле прямоугольника. Устанавливается в
    <margin-width> | inherit
    ;

    • 

    margin-top
    . Задает верхнее поле прямоугольника. Устанавливается в
    <margin-width> | inherit
    ;

    • 

    master-name
    . Задает или выбирает шаблон (master). Устанавливается в
    <name>
    ;

    • 

    number-columns-spanned
    . Задает число столбцов, занимаемых ячейкой таблицы. Устанавливается в
    <number>
    ;

    • 

    number-rows-spanned
    . Задает число строк, занимаемых ячейкой таблицы. Устанавливается в
    <number>
    ;

    • 

    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 | <length> | inherit
    ;

    • 

    page-width
    . Задает ширину страницы. Устанавливается в
    auto | indefinite | <length> | inherit
    ;

    • 

    position
    . Задает используемую схему размещения. Устанавливается в
    static | relative | absolute | fixed | inherit
    ;

    • 

    relative-position
    . То же, что и свойство CSS2 с тем же именем. Устанавливается в
    static | relative | inherit
    ;

    • 

    right
    . Определяет, насколько край содержимого прямоугольника (box) смещен влево от правой границы содержащего прямоугольник блока. Устанавливается в
    <length> | <percentage> | auto | inherit
    ;

    • 

    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, определяющую внешний ресурс. Устанавливается в
    <uri-specification> | inherit
    ;

    • 

    start-indent
    . Определяет расстояние от начального края прямоугольника содержимого области, содержащей блок, до начального края прямоугольника содержимого области этого блока. Устанавливается в
    <length> | inherit
    ;

    • 

    starts-row
    . Определяет, начинает ли эта ячейка строку. Устанавливается в
    true | false
    ;

    • 

    text-align
    . Определяет способ выравнивания встроенного содержимого блока. Устанавливается в
    start | center | end | justify | inside | outside | left | right | <string> | inherit
    ;

    • 

    text-decoration
    . Задает параметры оформления, добавляемого тексту элемента. Устанавливается в
    none | [ [ underline | no-underline] || [ overline | no-overline ] || [ line-through | no-line-through ] || [ blink | no-blink ] ] | inherit
    ;

    • 

    text-indent
    . Определяет выравнивание первой строки текста в блоке. Устанавливается в
    <length> | <percentage> | inherit
    ;

    • 

    text-shadow
    . Задает разделенный запятыми список теневых эффектов, которые нужно применить к тексту элемента. Устанавливается в
    none | <color> || <length> <length> <length>? ,]* <color> || <length> <length> <length>?] | inherit
    ;

    • 

    top
    . Определяет, насколько край содержимого смещен ниже верхнего края содержащего его блока. Устанавливается в
    <length> | <percentage> | auto | inherit
    ;

    • 

    vertical-align
    . Определяет вертикальное расположение. Устанавливается в
    baseline | middle | sub | super | text-top | text-bottom [ <percentage> | <length> | top | bottom | inherit
    ;

    • 

    visibility
    . Определяет, будут ли отображены генерируемые элементом прямоугольники. Устанавливается в
    visible | hidden | collapse | inherit
    ;

    • 

    white-space
    . Определяет способ обработки символов-разделителей (white-space) внутри элемента. Устанавливается в
    normal | pre | nowrap | inherit
    ;

    • 

    white-space-collapse
    . Задает способ обработки последовательных символов-разделителей. Устанавливается в
    false | true | inherit
    ;

    • 

    width
    . Задает ширину содержимого прямоугольников, созданных элементами уровня блока и замененными элементами. Устанавливается в
    <length> | <percentage> | auto | inherit
    ;

    • 

    wrap-option
    . Определяет наличие оболочки строк форматирующего объекта. Устанавливается в
    no-wrap | wrap | inherit
    .

    Не все свойства применимы ко всем объектам XSL-FO. В этой и следующей главах я буду явно перечислять свойства, применимые к используемым мной объектам. Заметьте также, что пока что ни в одном процессоре XSL-FO не реализованы все эти свойства.

    Мы вкратце рассмотрели структуру XSL-FO, теперь пора перейти к практике: сейчас мы подробно рассмотрим работу примера.

    Форматирование документа XML

    Чтобы посмотреть, как XSL-FO может форматировать данные XML, я воспользуюсь planets.xml (листинг 11.1).

    Листинг 11.1. planets.xml

    <?xml version="1.0"?>

    <?xml-stylesheet type="text/xml" href="planets.xsl"?>

    <PLANETS>

     <PLANET COLOR="RED">

      <NAME>Mercury</NAME>

      <MASS UNITS="(Earth = 1)">.0553</MASS>

      <DAY UNITS="days">58.65</DAY>

      <RADIUS UNITS="miles">1516</RADIUS>

      <DENSITY UNITS="(Earth = 1)">.983</DENSITY>

      <DISTANCE UNITS="million miles">43.4</DISTANCE><!--B перигелии-->

     </PLANET>

     <PLANET COLOR="WHITE">

      <NAME>Venus</NAME>

      <MASS UNITS="(Earth = 1)">.815</MASS>

      <DAY UNITS="days">116.75</DAY>

      <RADIUS UNITS="miles">3716</RADIUS>

      <DENSITY UNITS="(Earth = 1)">.943</DENSITY>

      <DISTANCE UNITS="million miles">66.8</DISTANCE><!--B перигелии-->

     </PLANET>

     <PLANET COLOR="BLUE">

      <NAME>Earth</NAME>

      <MASS UNITS="(Earth = 1)">1</MASS>

      <DAY UNITS="days">1</DAY>

      <RADIUS UNITS="miles">2107</RADIUS>

      <DENSITY UNITS="(Earth = 1)">1</DENSITY>

      <DISTANCE UNITS="million miles">128.4</DISTANCE><!--B перигелии-->

     </PLANET>

    </PLANETS>

    В этом первом примере я создам таблицу стилей 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

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        <fo:simple-page-master master-name="page"

         page-height="400mm" page-width="300mm"

         margin-top="10mm" margin-bottom="10mm"

         margin-left="20mm" margin-right="20mm">

         <fo:region-body

          margin-top="0mm" margin-bottom="10mm"

          margin-left="0mm" margin-right="0mm"/>

         <fo:region-after extent="10mm"/>

        </fo:simple-page-master>

       </fo:layout-master-set>

       <fo:page-sequence master-name="page">

        <fo:flow flow-name="xsl-region-body">

         <fo:block font-weight="bold" font-size="36pt"

          line-height="48pt" font-family="Times" color="blue">

          The Planets Table

         </fo:block>

         <xsl:apply-templates/>

        </fo:flow>

       </fo:page-sequence>

      </fo:root>

     </xsl:template>


     <xsl:template match="PLANET/NAME">

      <fo:block font-weight="bold" font-size="28pt"

       line-height="48pt" font-family="Times"

       font-style="italic">

       Planet:

       <xsl:apply-templates/>

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/MASS">

      <fo:block font-size="24pt" line-height="32pt"

       font-family="Times">

       <fo:inline text-decoration="underline">

        Mass

       </fo:inline>:

       <xsl:apply-templates/>

       [Earth = 1]

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/DAY">

      <fo:block font-size="24pt" line-height="32pt"

       font-family="Times">

       <fo:inline text-decoration="underline">

        Day

       </fo:inline>:

       <xsl:apply-templates/>

       [Earth = 1]

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/RADIUS">

      <fo:block font-size="24pt" line-height="32pt"

       font-family="Times">

       <fo:inline text-decoration="underline">

        Radius

       </fo:inline>:

       <xsl:apply-templates/>

       miles

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/DENSITY">

      <fo:block font-size="24pt" line-height="32pt"

       font-family="Times">

       <fo:inline text-decoration="underline">

        Density

       </fo:inline>:

       <xsl:apply-templates/>

       [Earth = 1]

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/DISTANCE">

      <fo:block font-size="24pt" line-height="32pt"

       font-family="Times">

       <fo:inline text-decoration="underline">

        Distance

       </fo:inline>:

       <xsl:apply-templates/>

       million miles

      </fo:block>

     </xsl:template>

    </xsl:stylesheet>

    После применения этой таблицы стилей для преобразования

    planets.xsl
    будет получен файл
    planets.fo
    , который при помощи форматирующих объектов XSL-FO создает документ с видом, показанным на рис. 11.1. Вот как выглядит
    planets.fo
    (листинг 11.3).

    Листинг 11.3. planets.fo

    <?xml version="1.0" encoding="UTF-8"?>

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

     <fo:layout-master-set>

      <fo:simple-page-master margin-right="20mm"

       margin-left="20mm" margin-bottom="10mm"

       margin-top="10mm" page-width="300mm"

       page-height="400mm" master-name="page">

       <fo:region-body margin-right="0mm" margin-left="0mm"

        margin-bottom="10mm" margin-top="0mm"/>

       <fo:region-after extent="10mm"/>

      </fo:simple-page-master>

     </fo:layout-master-set>

     <fo:page-sequence master-name="page">

      <fo:flow flow-name="xsl-region-body">

       <fo:block color="blue" font-family="Times"

        line-height="48pt" font-size="36pt" font-weight="bold">

        The Planets Table

       </fo:block>

       <fo:block font-style="italic" font-family="Times"

        line-height="48pt" font-size="28pt" font-weight="bold">

        Planet:

        Mercury

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Mass

        </fo:inline>:

        .0553

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fо:inline text-decoration="underline">

         Day

        </fo:inline>:

        58.65

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Radius

        </fo:inline>:

        1516

        miles

       </fo:block>

       <fo:block font-family="Times" line height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Density

        </fo:inline>:

        .983

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Distance

        </fo:inline>:

        43.4

        million miles

       </fo:block>

       <fo:block font-style="italic" font-family="Times" line-height="48pt"

        font-size="28pt" font-weight="bold">

        Planet:

        Venus

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Mass

        </fo:inline>:

        .815

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Day

        </fo:inline>:

        116.75

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Radius

        </fo:inline>:

        3716

        miles

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Density

        </fo:inline>:

        .943

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Distance

        </fo:inline>:

        66.8

        million miles

       </fo:block>

       <fo:block font-style="italic" font-family="Times" line-height="48pt"

        font-size="28pt" font-weight="bold">

        Planet:

        Earth

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Mass

        </fo:inline>:

        1

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Day

        </fo:inline>:

        1

        [Earth = 1]

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Radius

        </fo:inline>:

        2107

        miles

       </fo:block>

       <fo:block font-family="Times" line-height="32pt" font-size="24pt">

        <fo:inline text-decoration="underline">

         Density

        </fo:inline>:

        1

        [Earth = 1]

        </fo:block>

        <fo:block font-family=Times" line-height="32pt" font-size="24pt">

         <fo:inline text-decoration="underline">

          Distance

         </fo:inline>:

         128.4

         million miles

        </fo:block>

       </fo:flow>

      </fo:page-sequence>

    </fo:root>

    Для того чтобы обработать

    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>

    Первый форматирующий документ, который мы рассмотрим, — это

    <fo:root>
    , узел документа любого документа XSL-FO.

    Детьми форматирующего объекта

    <fo:root>
    являются единственный форматирующий объект
    <fo:layout-master-set>
    и последовательность из одного или нескольких элементов
    <fo:page-sequence>
    . Форматирующий объект
    <fo:layout-master-set>
    содержит все используемые в документе шаблоны, при помощи которых вы управляете созданием каждой страницы. Каждый объект
    <fo:page-sequence>
    представляет собой последовательность страниц, отформатированных нужных вам способом. Например, каждая глава в книге может быть сформирована из своей собственной последовательности страниц, и каждой последовательности страниц вы можете задать одни и те же верхний и нижний колонтитулы: «Глава 5: Незнакомец появляется снова».

    На первом шаге в таблице стилей XSLT, преобразующей

    planets.xml
    , я выбираю узел документа
    <PLANETS>
    и заменяю его на элемент
    <fo:root>
    , объявляющий префикс пространства имен «
    fo
    »:

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       .

       .

       .

    Элемент

    <fo:root>
    может содержать и схемы шаблонов, и последовательности страниц. Сначала я опишу объект
    <fo:layout-master-set>
    .

    Создание схемы набора шаблонов: <fo:layout-master-set>

    Шаблоны (master) могут быть определены для страниц, последовательностей страниц и областей. Элемент

    <fo:layout-master-set>
    содержит все используемые в документе шаблоны, включая шаблоны последовательностей (sequence master), страниц (page master) и областей (region master).

    Шаблоны страниц формируют отдельные страницы, шаблоны последовательностей страниц — последовательности страниц; шаблоны областей позволяют форматировать определенные области страницы. В следующем примере я создам единственный шаблон при помощи

    <fo:simple-page-master>
    .

    Шаблоны, которые вы хотите применить в документе, должны быть перечислены в элементе

    <fo:layout-master-set>
    , поэтому теперь я добавляю его в
    planets.xsl
    :

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        .

        .

        .

       </fo:layout-master-set>

       .

       .

       .

    Этот элемент содержит шаблон страницы, как определено в элементе

    <fo:simple-page-master>
    .

    Создание шаблона страницы: <fo:simple-page-master>

    Как можно догадаться из названия, шаблон страницы (page master) применяется для создания страницы. Шаблон страницы задает фактическую схему и конфигурацию страницы. Каждому шаблону страницы должно быть задано уникальное имя, к которому и нужно обращаться при работе с шаблоном.

    В настоящей спецификации XSL существует единственный вид шаблона страницы,

    <fo:simple-page-master>
    , и здесь я буду применять этот элемент для форматирования страниц. С объектом <
    fo:simple-page-master>
    можно использовать следующие свойства XSL-FO (их описание приведено в Приложении Б):

    • общие свойства полей для блоков:

    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
    . После этого шаблон стал именованным, и когда мне нужно создать страницы по этому шаблону, я обращаюсь к нему по этому имени. Я также задаю размеры и поля страницы при помощи свойств страницы и полей следующим образом:

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

       <fo:simple-page-master master-name="page"

        page-height="400mm" page-width="300mm"

        margin-top="10mm" margin-bottom="10mm"

        margin-left="20mm" margin-right="20mm">

        .

        .

        .

    В дополнение к заданию схемы расположения полей страницы, у

    <fo:simple-page-master>
    есть дети, определяющие одну или несколько областей страницы, что позволяет точно настроить схему расположения.

    Создание областей

    В версии 1.0 спецификации XSL у шаблонов страниц имелось пять областей (region). Центральная область, соответствующая основной части, телу страницы, называется областью тела (body region). Верхняя часть страницы, верхний колонтитул (header), называется передней областью (before region); нижняя часть страницы, нижний колонтитул (footer), называется задней областью (after region). В языках, которые читаются слева направо, как английский язык, левая часть страницы называется начальной областью (start region), а правая часть называется конечной областью (end region). В языках, которые читаются справа налево, начальная и конечная области меняются местами. Начальная и конечная области аналогичны боковым полям, расположенным по бокам области тела.

    Этим областям соответствуют следующие элементы XSL-FO:

    • 

    <fo:region-before>
    ;

    • 

    <fo:region-after>
    ;

    • 

    <fo:region-body>
    ;

    • 

    <fo:region-start>
    ;

    • 

    <fo:region-end>
    .

    С ними можно применять следующие свойства:

    • общие свойства границ, заполнения и заднего фона:

    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
    , задающее их размер, которым я здесь воспользуюсь:

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

       <fo:simple-page-master master-name="page"

        page-height="400mm" page-width="300mm"

        margin-top="10mm" margin-bottom="10mm"

        margin-left="20mm" margin-right="20mm">

        <fo:region-body margin-top="0mm" margin-bottom="10mm"

         margin-left="0mm" margin-right="0mm"/>

        <fo:region-after extent="10mm"/>

       </fo:simple-page-master>

      </fo:layout-master-set>

      .

      .

      .

    Это завершает используемый в документе шаблон, простой шаблон страницы «page», почему здесь также завершается и элемент

    <fo:layout-master-set>
    .

    В дополнение к элементу

    <fo:layout-master-set>
    , документ с форматирующими объектами, как правило, также содержит один или несколько элементов
    <fo:page-sequence>
    , задающих последовательности страниц, создаваемых по определенному в
    <fo:layout-master-set>
    шаблону, и я добавил в документ последовательность страниц.

    Создание последовательностей страниц: <fo:page-sequence>

    Что такое последовательность страниц? Это ряд страниц с одинаковыми характеристиками (например, глава в книге), которые при желании можно форматировать одинаковым способом. Страницы в результирующем документе в действительности создаются тогда, когда процессор XSL-FO обрабатывает элементы

    <fo:page-sequence>
    .

    Каждый элемент

    <fo:page-sequence>
    ссылается либо на элемент
    <fo:page-sequence-master>
    , либо на шаблон страницы, и фактическая схема страниц определяется этими шаблонами. Несколько более сложно создание последовательностей, у которых место расположения номера страницы меняется — номеру располагаются на разных сторонах страницы, как при создании страниц книги.

    К объекту

    <fo:page-sequence>
    применимы следующие свойства:

    • 

    country
    ;

    • 

    format
    ;

    • 

    language
    ;

    • 

    letter-value
    ;

    • 

    grouping-separator
    ;

    • 

    grouping-size
    ;

    • 

    id
    ;

    • 

    initial-page-number
    ;

    • 

    force-page-count
    ;

    • 

    master-name
    .

    В последней рекомендации XSL W3C шаблон страницы для последовательности страниц задается атрибутом

    master-name
    элемента
    <fo:page-sequence>
    . Я назвал свой простой шаблон страницы «page», и здесь я устанавливаю данный атрибут в это имя:

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

       <fo:simple-page-master master-name="page"

        page-height="400mm" page-width="300mm"

        margin-top="10mm" margin-bottom="10mm"

        margin-left="20mm" margin-right="20mm">

        <fo:region-body margin-top="0mm" margin-bottom="10mm"

         margin-left="0mm" margin-right="0mm"/>

        <fo:region-after extent="10mm"/>

       </fo:simple-page-master>

      </fo:layout-master-set>

      <fo:page-sequence master-name="page">

       .

       .

       .

      </fo:page-sequence>

      .

      .

      .

    Этот код определяет шаблон страницы, который будет использован для последовательности страниц. Теперь мне нужно задать содержимое (content) последовательности, что делается при помощи детей потока (flow) элемента

    <fo:page-sequence>
    .

    Создание объектов потока: <fo:flows>

    Объекты потока носят такое название потому, что текст в них «заливается» и выравнивается, заполняя страницу, программой, отвечающей за вывод на экран. Содержимое страницы управляется объектами потока.

    Есть два вида объектов потока:

    <fo:static-content>
    и
    <fo:flow>
    . Объект
    <fo:static-content>
    хранит содержимое (например, текст в верхних и нижних колонтитулах), которое будет повторяться на страницах последовательности (как мы увидим в главе 12). Объект
    <fo:flow>
    содержит сам текст, образующий содержимое документа.

    К

    <fo:flow>
    применимо следующее свойство:

    flow-name
    .

    Я воспользуюсь элементом

    <fo:flow>
    для обработки текстового содержимого
    planets.xml
    . Чтобы гарантировать, что текст будет преобразован в поток, я применю элемент
    <xsl:apply-templates>
    :

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        .

        .

        .

       </fo:layout-master-set>

       <fo:page-sequence master-name="page">

        <fo:flow flow-name="xsl-region-body">

         <xsl:apply-templates/>

        </fo:flow>

       </fo:page-sequence>

       .

       .

       .

    Здесь мы заканчиваем рассмотрение элемента

    <fo:page-sequence>
    ; я указал шаблон для этой последовательности, который предоставит процессору XSL-FO способ форматирования содержимого в страницах форматированного документа. После описания схемы страниц, которые я хочу создать, теперь, наконец, пора перейти к их содержимому. Первый элемент, отображающий содержимое, —
    <fo:block>
    .

    Создание содержимого уровня блока: <fo:block>

    Блоки играют важную роль в XSL-FO: они применяются для создания прямоугольных областей вывода, отделенных от других областей вывода в документе. Форматирующий объект

    <fo:block>
    применяется для форматирования таких элементов, как абзацы, заголовки, подписи к рисункам и таблицам и т.д. Вот пример из начала главы, где я создаю элемент блока и задаю различные свойства и текст в блоке:

    <fo:block font-family="Times" line-height="48pt" font-size="36pt">

     Welcome to XSL formatting.

    </fo:block>

    С объектом

    <fo:block>
    можно применять следующие свойства:

    • общие свойства доступа:

    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
    :

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        .

        .

        .

       </fo:layout-master-set>

       <fo:page-sequence master-name="page">

        <fo:flow flow-name="xsl-region-body">

        <fo:block font-weight="bold" font-size="36pt"

         line-height="48pt" font-family="Times" color="blue">

         The Planets Table

        </fo:block>

        <xsl:apply-templates/>

       </fo:flow>

      </fo:page-sequence>

      .

      .

      .

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

    font-style
    в «italic», и я подчеркиваю остальной текст при помощи свойства
    text-decoration
    элементов
    <fo:inline>
    , которые мы рассмотрим в следующей главе:

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        .

        .

        .

       </fo:layout-master-set>

       <fo:page-sequence master-name="page">

        .

        .

        .

       </fo:page-sequence>

      </fo:root>

     </xsl:template>


     <xsl:template match="PLANET/NAME">

      <fo:block font-weight="bold" font-size="28pt"

       line-height="48pt" font-family="Times" font-style="italiс">

       Planet:

       <xsl:apply-templates/>

      </fo:block>

     </xsl:template>


     <xsl:template match="PLANET/MASS">

      <fo:block font-size="24pt" line-height="32pt" font-family="Times">

       <fo:inline text-decoration="underline">

        Mass

       </fo:inline>:

       <xsl:apply-templates/>

       [Earth = 1]

      </fo:block>

     </xsl:template>

     .

     .

     .

    </xsl:stylesheet>

    Вот и все. Вы создали свое первое преобразование из XML в XSL-FO, преобразовав

    planets.xml
    в
    planets.fo
    . Процессор fop создаст из
    planets.fo
    файл
    planets.pdf
    , и вы можете вернуться к рис. 11.1 и посмотреть на результат.

    Это преобразование форматировало данные в

    planets.xml
    и отображало их в блоках, одно за другим. С другой стороны, в предыдущих главах мы видели данные планет в виде таблицы. Можно ли это сделать в XSL-FO? Никаких проблем.

    Создание таблиц

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

    <fo:table-and-caption>
    ;

    <fo:table>
    ;

    <fo:table-column>
    ;

    <fo:table-caption>
    ;

    <fo:table-header>
    ;

    <fo:table-footer>
    ;

    <fo:table-body>
    ;

    <fo:table-row>
    ;

    <fo:table-cell>
    .

    Создание таблиц в XSL-FO аналогично их созданию в HTML. Вы создаете элемент

    <fo:table>
    , содержащий всю таблицу целиком, затем форматируете каждый столбец при помощи элемента
    <fo:table-column>
    . После чего вы создаете элемент
    <fo:table-body>
    , чтобы задать тело таблицы. Элемент
    <fo:table-body>
    содержит все элементы
    <fo:table-row>
    , каждый из которых создает строку таблицы. Каждый элемент
    <fo:table-row>
    содержит элементы
    <fo:table-cell>
    , в которых содержатся данные ячеек таблицы.

    Следующий пример (листинг 11.4) демонстрирует работу с этими элементами. Приведенная таблица стилей XSLT преобразует

    planets.xml
    в документ XSL-FO, форматирующий данные планет в таблицу XSL-FO.

    Листинг 11.4. tables.xsl

    <?xml version="1.0"?>

    <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     xmlns:fo="http://www.w3.org/1999/XSL/Format"

     version="1.0">

     <xsl:template match="PLANETS">

      <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

       <fo:layout-master-set>

        <fo:simple-page-master master-name="page"

         page-height="400mm" page-width="300mm"

         margin-top="10mm" margin-bottom="10mm"

         margin-left="20mm" margin-right="20mm">

         <fo:region-body margin-top="0mm" margin-bottom="10mm"

          margin-left="0mm" margin-right="0mm"/>

         <fo:region-after extent="10mm"/>

        </fo:simple-page-master>

       </fo:layout-master-set>

       <fo:page-sequence master-name="page">

        <fo:flow flow-name="xsl-region-body">

         <fo:table>

          <fo:table-column column-width="30mm"/>

          <fo:table-column column-width="30mm"/>

          <fo:table-column column-width="30mm"/>

          <fo:table-column column-width="30mm"/>

          <fo:table-column column-width="30mm"/>

          <fo:table-column column-width="30mm"/>

          <fo:table-body>

           <fo:table-row>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Name

             </fo:block>

            </fo:table-cell>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Mass

             </fo:block>

            </fo:table-cell>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Day

             </fo:block>

            </fo:table-cell>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Radius

             </fo:block>

            </fo:table-cell>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Density

             </fo:block>

            </fo:table-cell>

            <fo:table-cell border-width="0.5mm">

             <fo:block font-size="18pt" font-weight="bold">

              Distance

             </fo:block>

            </fo:table-cell>

           </fo:table-row>

           <xsl:apply-templates/>

          </fo:table-body>

         </fo:table>

        </fo:flow>

       </fo:page-sequence>

      </fo:root>

     </xsl:template>


     <xsl:template match="PLANET">

      <fo:table-row>

       <xsl:apply-templates/>

      </fo:table-row>

     </xsl:template>


     <xsl:template match="NAME">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>


     <xsl:template match="MASS">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>


     <xsl:template match="DAY">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>


     <xsl:template match="RADIUS">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>


     <xsl:template match="DENSITY">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>


     <xsl:template match="DISTANCE">

      <fo:table-cell border-width="0.5mm">

       <fo:block font-size="18pt">

        <xsl:value-of select='.'/>

       </fo:block>

      </fo:table-cell>

     </xsl:template>

    </xsl:stylesheet>

    Вот результат после преобразования в документ XSL-FO (листинг 11.5).

    Листинг 11.5. tables.fo

    <?xml version="1.0" encoding="UTF-8"?>

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

     <fo:layout-master-set>

      <fo:simple-page-master margin-right="20mm" margin-left="20mm"

       margin-bottom="10mm" margin-top="10mm" page-width="300mm"

       page-height="400mm" master-name="page">

       <fo:region-body margin-right="0mm" margin-left="0mm"

        margin-bottom="10mm" margin-top="0mm"/>

       <fo:region-after extent="10mm"/>

      </fo:simple-page-master>

     </fo:layout-master-set>

     <fo:page-sequence master-name="page">

      <fo:flow flow-name="xsl-region-body">

       <fo:table>

        <fo:table-column column-width="30mm"/>

        <fo:table-column column-width="30mm"/>

        <fo:table-column column-width="30mm"/>

        <fo:table-column column-width="30mm"/>

        <fo:table-column column-width="30mm"/>

        <fo:table-column column-width="30mm"/>

        <fo:table-body>

         <fo:table-row>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Name

           </fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Mass

           </fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Day

           </fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Radius

           </fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Density

           </fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-weight="bold" font-size="18pt">

            Distance

           </fo:block>

          </fo:table-cell>

         </fo:table-row>

         <fo:table-row>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">Mercury</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">.0553</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">58.65</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">1516</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">.983</fо:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">43.4</fо:block>

          </fo:table-cell>

         </fo:table-row>

         <fo:table-row>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">Venus</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">.815</fо:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">116.75</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">3716</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">.943</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">66.8</fо:block>

          </fo:table-cell>

         </fo:table-row>

         <fo:table-row>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">Earth</fо:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">1</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">1</fо:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">2107</fо:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">1</fo:block>

          </fo:table-cell>

          <fo:table-cell border-width="0.5mm">

           <fo:block font-size="18pt">128.4</fо:block>

          </fo:table-cell>

         </fo:table-row>

        </fo:table-body>

       </fo:table>

      </fo:flow>

     </fo:page-sequence>

    </fo:root>

    После обработки этого документа,

    tables.fo
    , процессором fop будет создан файл
    tables.pdf
    , который показан на рис. 11.2. Вот как выглядит таблица XSL-FO, хотя существует также весьма много других параметров — например, можно задать цвет заднего фона ячеек при помощи свойства
    background-color
    . По умолчанию в таких таблицах отсутствуют границы, но я добавил границу толщиной в 0,5 мм при помощи свойства
    border-width
    . Заметьте также, что для того, чтобы установить размер шрифта для текста в каждой ячейке, я использую блок внутри каждой ячейки таблицы:

    <fo:table-cell border-width="0.5mm">

     <fo:block font-size="18pt">Earth</fo:block>

    </fo:table-cell>

    Рис. 11.2. Таблица, отформатированная при помощи XSL-FO, в Adobe Acrobat Reader


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

    <fo:table>
    .

    Создание таблиц: <fo:table>

    Как можно догадаться из названия, элемент

    <fo:table>
    применяется для создания новой таблицы. Сама таблица состоит из необязательного заголовка, необязательного подстрочного примечания и одного или более тел таблицы (table body). Таблица из ячеек, выровненная по строкам и столбцам, выводится в теле таблицы.

    С элементом

    <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>
    :

    <fo:table>

     .

     .

     .

    </fo:table>

    Следующий шаг в создании таблицы — задать столбцы таблицы при помощи

    <fo:table-column>
    .

    Создание столбцов таблицы: <fo:table-column>

    Для каждого столбца в таблице нужно включить один элемент

    <fo:table-column>
    . Этот элемент позволяет задать характеристики ячеек в одном и том же столбце таблицы. Одно из самых важных свойств здесь — свойство
    column-width
    , определяющее ширину каждого столбца.

    С элементом

    <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>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     .

     .

     .

    </fo:table>

    После задания каждого столбца создается тело таблицы.

    Создание тел таблицы: <fo:table-body>

    Тело таблицы (table body) содержит фактическое содержимое таблицы; тела создаются при помощи элемента

    <fo:table-body>
    . Этот элемент содержит элементы
    <fo:table-row>
    , которые, в свою очередь содержат элементы
    <fo:table-cell>
    , содержащие данные таблицы.

    С элементом

    <fo: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-body>
    :

    <fo:table>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-body>

      .

      .

      .

     </fo:table-body>

    </fo:table>

    После создания тела таблицы нужно создать строки таблицы при помощи элемента

    <fo:table-row>
    — по одному элементу для каждой строки.

    Создание строк таблицы: <fo:table-row>

    Аналогично таблицам HTML, для создания строк таблицы применяется элемент

    <fo:table-row>
    , и каждая строка может содержать ячейки таблицы. Как и браузеры HTML, процессор XSL-FO определяет размеры таблицы по количеству строк.

    С элементом

    <fo:table-row>
    можно применять следующие свойства:

    • общие свойства доступа:

    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-row>
    следующим образом:

    <fo:table>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-body>

      <fo:table-row>

       .

       .

       .

      </fo:table-row>

      <fo:table-row>

       .

       .

       .

      </fo:table-row>

     </fo:table-body>

    </fo:table>

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

    Создание ячеек таблицы: <fo:table-cell>

    Снова, почти как при создании таблицы в HTML, вы помещаете данные в отдельные ячейки таблицы при помощи элемента

    <fo:table-cell>
    . Заметьте: чтобы задать шрифт и другие характеристики этого содержимого, внутри каждого элемента
    <fo:table-cell>
    можно заключить элемент
    <fo:block>
    . При желании вы можете связать ячейку таблицы с определенным столбцом при помощи свойства
    column-number
    или даже растянуть ячейку на несколько строк и столбцов, как в таблицах HTML.

    С элементом

    <fo:table-cell>
    можно применять следующие свойства:

    • общие свойства доступа:

    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
    я поместил в ячейки таблицы и подписи к каждому столбцу, и данные таблицы следующим образом:

    <fo:table>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-column column-width="30mm"/>

     <fo:table-body>

      <fo:table-row>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt">

         Name

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt">

         Mass

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt">

         Day

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt">

         Radius

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt">

         Density

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-weight="bold" font-size="18pt"

         Distance

        </fo:block>

       </fo:table-cell>

      </fo:table-row>

      <fo:table-row>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         Mercury

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         .0553

        </fо:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         58.65

        </fо:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         1516

        </fo:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         .983

        </fо:block>

       </fo:table-cell>

       <fo:table-cell border-width="0.5mm">

        <fo:block font-size="18pt">

         43.4

        </fo:block>

       </fo:table-cell>

      </fo:table-row>

      .

      .

      .

     </fo:table-body>

    </fo:table>

    Теперь все готово — результат показан на рис. 11.2, где вы можете увидеть полностью отформатированную таблицу, созданную процессором fop. Теперь вы знаете, как создавать таблицы при помощи форматирующих объектов XSL.

    Безусловно, можно еще много сказать о XSL-FO. В следующей главе мы рассмотрим работу со списками, размещение, колонки, последовательности страниц и другие элементы.







     


    Главная | В избранное | Наш E-MAIL | Добавить материал | Нашёл ошибку | Наверх