Чтение онлайн

ЖАНРЫ

Технология XSLT

Валиков Алексей Н.

Шрифт:
Листинг 9.6. XML-документ каталога

<?xml version="1.0" encoding="windows-1251"?>

<catalog>

 <category title="Компьютеры">

<category title="Настольные компьютеры"/>

<category title="Серверы"/>

 </category>

 <category title="Комплектующие">

<category title="Процессоры"/>

<category title="Материнские
платы"/>

 </category>

 <category title="Расходные материалы">

<category title="Картриджи">

<category title="Картриджи для плоттеров"/>

<category title="Картриджи для принтеров"/>

</category>

<category title="Тонеры"/>

<category title="Бумага"/>

 </category>

</catalog>

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

□ При помощи ключа и уникального идентификатора, сгенерированного функцией

generate-id
, мы найдем в дереве требуемую категорию и присвоим ее переменной
$category
.

□ Воспользовавшись осью

ansector-or-self
, мы найдем все надкатегории данной, то есть все категории, которые прямо или косвенно содержат найденную. Путь выборки будет иметь вид
$category/ancestor-or-self::category
. Найденное множество мы присвоим переменной
$path
.

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

$path
. Проверять это мы будем при помощи условия
count(.|$path)=count($path)
.

Искомое преобразование в итоге запишется в виде.

Листинг 9.7. Преобразование обрабатывающее наш каталог

<?xml version="1.0" encoding="windows-1251"?>

<xsl:stylesheet

 version="1.0"

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

 <!-- Выводим документ в формате html и кодировке windows-1251 -->

 <xsl:output method="html" encoding="windows-1251"/>

 <!--

| Переменная, которая содержит уникальный

| идентификатор выбранного узла дерева

+-->

 <xsl:param name="current" select="''"/>

 <!-- Определение ключа категории -->

 <xsl:key name="cat" match="category" use="generate-id(.)"/>

 <!--
Находим текущую категорию -->

 <xsl:variable name="category" select="key('cat',$current)"/>

 <!--

| Находим надкатегории текущей категории, узлы которых

| мы будем раскрывать в дереве

+-->

 <xsl:variable name="path"

select="$category/ancestor-or-self::category"/>

 <!-- Шаблон обработки каталога -->

 <xsl:template match="catalog">

<xsl:apply-templates select="category"/>

 </xsl:template>

 <!-- Шаблон обработки категории-->

 <xsl:template match="category">

<!-- Параметр, указывающий отступ -->

<xsl:param name="indent"/>

<!-- Выводим отступ -->

<xsl:value-of select="$indent"/>

<!-- Выводим информацию о категории в виде ссылки -->

<а href="#">

<!-- Перед названием категории выводим соответствующую иконку -->

<img height="11" width="11" border="0">

<xsl:choose>

<!--

| Если категория не содержит субэлементов,

| выводим иконку с точкой

+-->

<xsl:when test="not(*)">

<xsl:attribute name="src">images/dot.gif</xsl:attribute>

</xsl:when>

<!--

| Если категория принадлежит ветке выбранной категории,

| выводим иконку с минусом, что означает раскрытую ветку

+-->

<xsl:when test="count(.|$path)=count($path)">

<xsl:attribute name="src">images/minus.gif</xsl:attribute>

</xsl:when>

<!--

| Если категория не принадлежит ветке выбранной категории,

| выводим иконку с плюсом, что означает нераскрытую ветку

+-->

<xsl:otherwise>

<xsl:attribute name="src">images/plus.gif</xsl:attribute>

</xsl:otherwise>

</xsl:choose>

</img>

<!--

Поделиться с друзьями: