Вторник, 16.06.2026, 13:57
Приветствую Вас Гость | RSS
Поиск по каталогу
Главная страница | Каталог статей | Регистрация | Вход

Информационные технологии
Форма входа
Меню сайта

Категории каталога
php [246]
perl [1]
perl
ASP [1]
AJAX [0]

Друзья сайта

Наш опрос
Оцените мой сайт
Всего ответов: 69

Начало » Статьи » Web программирование » php

Преобразование XML + XSLT с помощью Sablotron продолжение
-->
* в шаблоне использован параметр match="a[@href]" — этот шаблон будет применён только к тем тегам ссылок, в которых есть поле href и пропустит якоря (<a name="xxx"></a>).

Невалидный код и


Кажущаяся необходимость писать валидный XML-код так же отпугивает многих неофитов XSLT. Хорошо, с завтрашнего дня будем писать статьи только валидно, благо дома можно проверить, нет ли в тексте XML-ошибки — mismatched tag или invalid token, — с этим как-нибудь справимся. Но ведь, по-хорошему, нужно и весь архив перевести в валидный код! И я так тоже думал, когда появилась возможность переделывать сайт на XML.

Решение проблемы довольно простое: не хочешь — не пиши валидно. Пиши, как привык, — без кавычек в атрибутах тегов, используй простой <br> и прочее. Достаточно заключить текст в контейнер <![CDATA[ ... ]]> (пример ниже).

Что касается &nbsp;, то здесь дела такие: элемента nbsp в XML нет. Есть lt, gt, quot, но не nbsp (вполне логично — это ведь non-braking space, который относится к форматированию и придуман для HTML). Поэтому его нужно объявить в документе, либо использовать только внутри <![CDATA[...]]>.

Пример #4:

XML:


<text>
    <
bad-markup><![CDATA[В этом <a href=http://detail.phpclub.net>тексте</a> применена
невалидная разметка. <br> И ничего страшного.]]></bad-markup>
    <
quote>Люди, памажите, сами мы не местные!</quote>
    <
hr/>
    <
strong>Запомните и эти шаблоны тоже!</strong>
</
text>


XSLT:


<xsl:template match="text"><![CDATA[ >>> и в XSL можно делать то же самое! <<< ]]>
<
xsl:apply-templates/></xsl:template>

<
xsl:template match="bad-markup">
    <
xsl:value-of select="." disable-output-escaping="yes"/>
</
xsl:template>

<
xsl:template match="*">
    <
xsl:copy>
        <
xsl:apply-templates select="@*" />
        <
xsl:apply-templates/>
    </
xsl:copy>
</
xsl:template>

<
xsl:template match="text()">
    <
xsl:value-of select="." disable-output-escaping="yes"/>
</
xsl:template>

<
xsl:template match="@*|node()">
    <
xsl:copy>
        <
xsl:apply-templates select="@*|node()"/>
    </
xsl:copy>
</
xsl:template>


Очень удобно! Большие изменения в архив вносить не придётся. Можно начать писать валидно, а продолжать как попало. А можно комбинировать эти два подхода. Чтобы не писать в архивные файлы тег CDATA, я сделал простое преобразование при помощи регулярных выражений (важно так же помнить, что один тег CDATA не должен содержать в себе другой).


$doc = preg_replace("~<(p|h[1-3]|pre)>(.*?)</\\1>~", "<\\1>\\2</\\1>", $doc);


Циклы


Допустим, нам нужно сделать форму для редактирования статьи, в том числе её даты. Для удобства пользования надо сделать три раскрывающихся списка (далее — "крутилки") — дата от 1 до 31, месяц, год. Первое решение, которое приходит в голову — сделать HTML-код крутилок в php, вставить в XML в контейнере CDATA, а затем вывести в XSL с параметром disable-output-escaping="yes".

На самом деле, XSLT может и это. Достаточно вставить в данные XML число, номер месяца и год. Крутилки можно нарисовать сразу в XSLT.

Напишем шаблон, не предназначенный ни для какого элемента документа. Он будет вызываться командой xsl:call-template и получать два параметра: значение счётчика и максимум. Сперва он будет выводить нужные нам данные со значением счётчика, затем вызывать самого себя с параметрами максимум и счётчик, увеличенный на 1. Пример #5:

XML:


<month-name>Февраль</month-name>
<
month-name>Март</month-name>
<
month-name>Апрель</month-name>
<
month-name>Май</month-name>
<
month-name>Июнь</month-name>
<
month-name>Июль</month-name>
<
month-name>Август</month-name>
<
month-name>Сентябрь</month-name>
<
month-name>Октябрь</month-name>
<
month-name>Ноябрь</month-name>
<
month-name>Декабрь</month-name>

<
article>
    ...
    <
day>7</day>
    <
month>10</month>
    <
year>2002</year>
</
article>


XSLT:


<xsl:template match="article">
    ...
    <
select name="d">
    <
xsl:call-template name="day">
        <
xsl:with-param name="count">1</xsl:with-param>
    </
xsl:call-template>
    </
select>
    <
select name="m">
    <
xsl:call-template name="month">
        <
xsl:with-param name="count">1</xsl:with-param>
    </
xsl:call-template>
    </
select>
    ...
</
xsl:template>

<
xsl:template name="day">
    <
xsl:param name="count"/>
    <
option value="{$count}">
        <
xsl:if test="$count = //artcile/day">
            <
xsl:attribute name="selected">yes</xsl:attribute>
        <
xsl:if>
        <
xsl:value-of select="$count"/>
    </
option>
    <
xsl:if test="$count &lt; 31">
        <
xsl:call-template name="day">
            <
xsl:with-param name="count">
                <
xsl:value-of select="$count + 1"/>
            </
xsl:with-param>
        </
xsl:call-template>
    </
xsl:if>
</
xsl:template>

<
xsl:template name="month">
    <
xsl:param name="count"/>
    <
option value="{$count}">
        <
xsl:if test="$count = //artcile/month">
            <
xsl:attribute name="selected">yes</xsl:attribute>
        <
xsl:if>
        <
xsl:value-of select="//month-name[position() = $count]"/>
    </
option>
    <
xsl:if test="$count &lt; 12">
        <
xsl:call-template name="month">
            <
xsl:with-param name="count">
                <
xsl:value-of select="$count + 1"/>
            </
xsl:with-param>
        </
xsl:call-template>
    </
xsl:if>
</
xsl:template>


Оставляю вам в качестве домашнего задания шаблон для вывода крутилки с годом.

Резюме


Как видите, многое из того, что пишется в php-скриптах, даже при использовании класса шаблона, можно успешно спустить в XSLT. Но стОит ли заниматься этим?

Ответ зависит от условий работы в вашем проекте. Второй момент — технологичность работы.

Допустим, я захочу сделать на этом сайте меню быстрой навигации — раскрывающийся список со всеми статьями, — чтобы пользователь мог выбрать статью из списка и сразу перейти к ней. Ещё я захочу оставить список последних материалов (сейчас он находится справа вверху).

Если делать это при помощи класса шаблона типа FastTemplate, нужно два специальных блока и дополнительный код в php, который бы объявлял в шаблоне блок для списка всех статей и отдельно блок для списка 10 последних. Аналогичные действия необходимы в таком случае и при работе без класса шаблона. При работе с XML достаточно всего лишь одного набора данных "Дата => Статья", из которого в XSL-документе строятся и листбокс быстрого перехода, и список последних статей.

А если вдруг понадобится неважно для чего сделать другое оформление сайта (например, версия для WAP, или просто редизайн), в котором будет решено отказаться от списка 10 последних материалов. В случае первых двух технологий — класс шаблона и смешанный код — нужно будет убрать часть php кода, в случае XSLT изменения коснутся только XSL-файла. Такой процесс более технологичен, поскольку невозможно сделать новые ошибки в php-скриптах (а теперь представьте обратный случай — списка 10 последних статей не было, но его решили добавить!).

Итак, выбор остаётся за вами, а я как мог привёл сильные стороны технологии и доводы в пользу использования XML в проектах.
Категория: php | Добавил: freeone (10.05.2007) | Автор: Дмитрий Лебедев
Просмотров: 737 | Рейтинг: 0.0 |

Всего комментариев: 0
Имя *:
Email *:
Код *:

Copyright Информационные технологии © 2006