Необходимость тщательно отслеживать в таблице стилей XSLT всю иерархию XML-документа может показаться неудобной. Это особенно заметно, если документ не следует какой-то стабильной, предсказуемой схеме, вроде периодической таблицы химических элементов, а представляет собой разнородный набор текста и разметки, как многие веб-страницы. В этих случаях нужно иметь общие правила, которые могут найти элемент и применить к нему шаблон вне зависимости от того, где он находится в исходном документе.
Чтобы облегчить эту работу, в XSLT имеется несколько дефолтных правил-шаблонов, которые имплицитно включаются во все таблицы стилей. Первое дефолтное правило соответствует корню и элементным узлам и применяет шаблон ко всем дочерним узлам. Второе дефолтное правило соответствует текстовым узлам и атрибутам, копируя их значения в выходной поток. В сумме эти два правила приводят к тому, что даже пустая таблица стилей XSLT, в которой есть только один пустой элемент xsl:stylesheet
, прямо выдаст символьные данные исходного XML-документа.
Первое дефолтное правило применяется к элементным узлам и корневому узлу:
<xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template>
Запись *|/
- это сокращение XPath, означающее "любой элементный узел или корневой узел." Задача этого правила - обеспечить рекурсивную обработку всех элементов, даже если к ним не применяется ни одно другое явно заданное правило. То есть, пока какое-то другое правило не переиграет это (особенно это касается корневого элемента), будут обрабатываться все элементные узлы.
Однако, если имеется явно заданное правило для любого родительского узла, дефолтное правило больше не будет активизироваться для его дочерних элементов, если правило-шаблон для родительского узла не содержит элемент xsl:apply-templates
. Например, можно прекратить всю обработку, соответствующую корневому элементу, не применять шаблоны к дочерним узлам и не использовать xsl:for-each
, если воспользоваться следующим правилом:
<xsl:template match="/"> </xsl:template>
Исключительно наблюдательные читатели могли заметить несколько примеров, которые, кажется, выводят содержание некоторых элементов, но при этом на самом деле не используют значения выводимых элементов! Это содержимое обрабатывается дефолтным правилом для текстовых и атрибутных узлов. Правило таково:
<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>
Это правило соответствует всем текстовым и атрибутным узлам (match="text()
|@*"
) и выводит их значение (<xsl:value-of select="."/>
). Другими словами, правило копирует текст из исходного документа в выходной. Это правило гарантирует, что по крайней мере текст элементов будет выводиться, даже если это не указано ни одним правилом. Это правило может быть переиграно другим, определенным для конкретного элемента - если вы хотите получить на выходе не просто его текстовое содержимое.
Кроме того, это правило копирует значения атрибутов (но не их имена). Однако, происходит преобразование из атрибутов в исходном документе в простой текст на выходе. Поскольку не существует дефолтного правила, которое бы применяло к атрибутам, это правило не будет активировано до тех пор, пока какое-то другое не-дефолтное правило в таблице стилей не применит шаблоны к атрибутам одного или нескольких элементов.
Существует также дефолтное правило для процессуальных инструкций и комментариев. Оно говорит: с ними ничего не делать, то есть попросту убирать из выходного документа комментарии и процессуальные инструкции, будто их не существует. Правило выглядит не так:
<xsl:template match="processing-instruction()|comment()"/>
Конечно, вы можете заменить это правило своими собственными правилами для обработки процессуальных инструкций и комментариев, если нужно.
В совокупности дефолтные правила означают: если применить к XML-документу пустую таблицу стилей, в которой нет ничего, кроме пустого элемента xsl:stylesheet
или xsl:transform
(как на листинге 17-14), из исходного документа в выходной копируется все секции #PCDATA
, содержащиеся в элементах исходного документа. Но в выходном документе будет отсутствовать разметка. Это правила чрезвычайно низкого приоритета, поэтому правила с любыми другими соответствиями будут иметь приоритет над дефолтными правилами.
Листинг 17-14: Пустая таблица стилей XSLT
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> </xsl:stylesheet>
Одна из основных причин трудностей и ошибок в связи с реализацией XSLT в Internet Explorer 5.0 и 5.5, заключается в том, что IE не предоставляет ни одного из этих дефолтных правил. Вам нужно заботиться о том, чтобы каждому узлу, содержание которого вы хотите вывести (включая его потомков), имелось явное соответствие в одном из шаблонов.