Стилевые таблицы XSL

Что такое XSL?

Правила XSL

  • Корневое правило
  • Отношения между элементами
  • Приоритеты правил
  • Использование атрибутов элементов
  • Фильтрация элементов

    Определение функций и глобальных переменных

    Встроенные функции XSL

     

    Что такое XSL?

    В предыдущем разделе для вывода элементов XML- документа на экран броузера мы применяли Java Script-сценарии Однако, как уже отмечалось, для этих целей предпочтительней использование специально предназначенного для этого средства - стилевых таблиц XSL(Extensible Stylesheet Language).

    Стилевыми таблицами (стилевыми листами) принято называть специальные инструкции, управляющие процессом отображения элемента в окне программы-клиента(например, в окне броузера). Предложенные в качестве рекомендация W3C, каскадные стилевые таблицы(CSS- Cascading Style Sheets) уже больше года используются Web- разработчиками для оформления Web- страниц.

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

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

    Некоторые его отличия от CSS:
    Во-первых, стилевые таблицы XSL позволяют определять оформление элемента в зависимости от его месторасположения внутри документа, т.е. к двум элементам с одинаковым названием могут применяться различные правила форматирования.
    Во-вторых, языком, лежащем в основе XSL, является XML, а это означает, что XSL более гибок, универсален и у разработчиков появляется возможность использования средства для контроля за корректностью составления таких стилевых списков(используя DTD или схемы данных)
    В-третьих, таблицы XSL не являются каскадными, подобно CSS, т.к. чрезвычайно сложно обеспечить "каскадируемость" стилевых описаний, или, другими словами, возможность объединения отдельных элементов форматирования путем вложенных описаний стиля, в ситуации, когда структура выходного документа заранее неизвестна и он создается в процессе самого разбора. Однако в XSL существует возможность задавать правила для стилей, при помощи которых можно изменять свойства стилевого оформления, что позволяет использовать довольно сложные приемы форматирования.

    Рассмотрим основные структурные элементы XSL, используемые, в частности, в конверторе msxsl, для создания оформления XML-документов.

    Правила XSL

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

    Элементы XML, к которым будет применяться форматирование, обозначаются в XSL дескриптором <target-element/>;. Для указания элемента с конкретным названием (название элемента определяется тэгами, его обозначающими), т.е. определения класса элемента, можно использовать атрибут type="<имя_элемента>"

    Вот пример простейшего XSL-документа, определяющего форматирование для фрагмента <flower>rose</flower> :

    <xsl>
    <rule>
    <target-element type="flower"/>
    <p color="red" font-size="12">
    <children/>
    </p>
    </rule>
    </xsl> 
    

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

    Инструкция <target-element> указывает на то, что данное правило определяет элемент. Параметром type="flower" задается название XML-элемента, для которого будет использоваться это правило. Программа-конвертор будет использовать HTML-тэги, помещенные внутри блока <rule></rule> для форматирования XML-элемента, которому "предназначался" текущий блок. В том случае, если для какого-то элемента XML шаблон не определяется, в выходной документ будут добавлены тэги форматирования по умолчанию (например, <DIV></DIV> )

    Процесс разбора XSL-правил является рекурсивным, т.е. если у элемента есть дочерние элементы, то программа будет искать определения этих элементов, расположенных "глубже" в дереве документа. Указанием на то, что необходимо повторить процесс разбора XML документа, теперь уже для дочерних элементов, является инструкция <children/>. Дойдя до нее, анализатор выберет из иерархического дерева XML- элементов нужную ветвь и найдет в XSL-шаблонах правила, определяющие форматирование этих нижележащих элементов. В том случае, если вместо <children> мы укажем инструкцию <empty/>;, программа закончит движение по данной ветви и возвратится назад, в родительское правило. При этом текущее правило никакой информации в выходном HTML-документе изменять не будет, т.к. <empty/> в данном случае означает, что содержимое элемента отсутствует.

    Если в одном правиле <target-element> используется несколько раз, то инструкции по форматированию будут распространены на все описываемые внутри него XML-элементы, т.е. можно задавать единый шаблон форматирования для нескольких элементов одновременно:

    <xsl>
    <rule>
    <target-element type="item1"/>
    <target-element type="item2"/>
    <target-element type="item3"/>
    <hr>
    <children/>
    <hr>
    </rule>
    </xsl> 
    

    Корневое правило

    Разбор любого XSL- документа всегда начинается с правила для корневого элемента, в котором определяется область всего разбираемого XML документа и поэтому тэги форматирования, помещенные сюда, будут действовать на весь документ в целом. Для обозначения корневого правила необходимо включить в него элемент <root/>.

    Отношения между элементами

    Дочерние элементы в XML-документе всегда находятся внутри области, определяемой тэгами родительского по отношению к ним элемента. Для того, чтобы точно указать месторасположение обрабатываемого элемента в дереве XML, в XSL используется дополнительный тэг <element>;. При помощи него можно указать, какие элементы должны предшествовать текущему, а какие - следовать после него.

    Приоритеты правил

    В том случае, если внутри XSL- документа встречается несколько правил для одного и того же элемента, то msxsl будет использовать то из них, которое более точно определяет позицию данного элемента.

    В общем случае приоритет правил определяется следующим образом (в порядке убывания приоритета):

    • правила, помеченные специальным тэгом <importance>
    • правила с наибольшим значением атрибута id, если он определен
    • правила с наибольшим значением атрибута class, если он определен
    • правила, имеющие наибольшую вложенность, определяемую тэгом <element>
    • правила, использующие атрибут type совместно с <target-element>
    • правила, в которых отсутствует атрибут type в <target-element> или <element>
    • правила с более высоким приоритетом, задаваемым атрибутом priority тэга <rule>
    • правила с наибольшим значением квалификаторов <only>, <position>, <attribute>

    Использование атрибутов элементов

    Применительно к <target-element> и <element> в правилах также могут использоваться специальные элементы <attribute>;, при помощи которых можно уточнять характеристики обрабатываемых элементов, задавая различные инструкции форматирования для одинаковых элементов с различными атрибутами. Указываемые в <attribute> параметры name и value определяют атрибут XML, который должен иметь текущий обрабатываемый элемент. Например, в следующем фрагменте все элементы с атрибутом free_lance ="true" будут выделены в выходном HTML- документе серым цветом

    <rule>
    <target-element type="author">
     <attribute name="free_lance" value="true">
            </target-element>
    <p color="gray">
    <children/>
    </p>
     </rule>
    

    Фильтрация элементов

    Одним из самых мощных средств XSL является возможность сортировки и выборки элементов, выделяемых из общего дерева элементов документа. Для этого используется элемент <select-elements>;, который заменяет <children/> в правилах, определяя те элементы, которые следует обработать в процессе рекурсивного обхода. Например, в следующем примере будут обработаны только элементы <author>:

    <rule>
    <target-element type=" staff"/>
    <div>
    <select-elements>
    <target-element type = "author"/>
    </select-elements>
    </div>
    </rule>
    

    Элемент <select-elements> сам по себе не определяет шаблон форматирования, он лишь управляет работой анализатора, обозначая, подобно <children/>, "нижележащие" элементы. В приведенном примере элемент <author> должен быть расположен внутри элемента <staff>

    Для того, чтобы в шаблоне выделить не только собственные дочерние элементы, но и дочерние элементы потомков, т.е. использовать несколько уровней вложенности, необходимо задать параметр from = "descendants". Если параметр имеет значение "children", что указывает на то, что выбор должен производится из списка собственных дочерних элементов, то атрибут from может опускаться, т.к. "children" является значением по умолчанию.

    Определение функций и глобальных переменных

    Аналогично тэгу <SCRIPT> в HTML, элемент <define-script> содержит функции и определения глобальных переменных. Обычно в XSL-документе определяется один элемент <define-script>, расположенный в самом начале.

    <xsl>
    <define-script>
    <![CDATA[
    var fontSize=12;
    function getColor(elem){
    return elem.children.item("color",0).text; 
                    // Возвращает содержимое дочернего элемента <color>
    }]]>
    </define-script>
    <rule>
    <target-element type = "flower">
    <div background-color="=getColor(this)"; font-size="=fontSize">
    <children/>
    </div>
    </rule>
    </xsl>
    

    Если применить эти правила к такому фрагменту XML- документу:

    <xml>
    <flower>
    rose
    <color>red</color> 
    </flower>
    

    , то на выходе HTML -документ будет содержать следующие элементы:

    <div background-color="red"; font-size="12">
    

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

    Использование Java Script для HTML

    Создавая шаблон HTML-документа, Вы можете указывать в нем практически любые элементы HTML, в том числе и блоки <SCRIPT>, внутри которых можно задавать любые конструкции Java Script, используя для этого область CDATA.

    Встроенные функции XSL

    В завершении приведем список внутренних функций, которые можно использовать в JavaScript –сценариях, предназначенных для анализатора msxsl:

    Ancestor(elementType, elem) Возвращает для текущего элемента ссылку на ближайший родительский элемент заданного типа. Если такого элемента нет или текущий элемент пустой, то возвращает null
    ChildNumber(elem) Возвращает индекс текущего элемента в списке других дочерних элементов данного типа.
    AncestorChildNumber() Возвращает номер ближайшего предка текущего элемента или null, если такового не существует
    path(xsl) Возвращает массив, содержащий "путь" к текущему элементу - в каждую ячейку этого массива помещается цифровое значение, указывающее на количество элементов одинакового типа, находящихся на текущем уровне вложенности. Первым значением этого массива будет представлен корневой элемент, последним - текущий. Размер массива определяет глубину вложенности текущего элемента.
    HierarchicalNumberRecursive(elementType,elem) Метод, похожий на метод path, но возвращает только дочерние элементы
    FormatNumber(n,format) Возвращает строку - символьное представление номера(т.е. "один", "два" и т.д.). Возможно определение следующих форматов:
    "1" - 0,1,2,..
    "01" - 01,02,03,...
    "a" - a,b,c,..z, aa, ab,..zz
    "A" - A,..,Z,AA, .. ZZ
    FormatNumberList(list,format,separator) Возвращает строку, представляющую список, элементами которого являются символьные представления чисел

    Пример XSL-документа

    Домой