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

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

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

Друзья сайта

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

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

Преобразование XML + XSLT с помощью Sablotron
Альтернативное введение в использование XSL Transformations в PHP при помощи Sablotron.

Данный материал следует воспринимать как альтернативное введение в использование XSLT с Sablotron в PHP.

Термины XSL и XSLT близки друг к другу, и новичкам их можно считать синонимами. Подробности, в чём же различия, описаны в спецификации XSL Transformations W3C.

Все, кто интересовался возможностями XSLT, читал стандартный пример из мануала, либо примеры, приводимые в статьях, посвящённых XSLT, на разных сайтах. Работающий пример из этой же серии:


<?php

$xmlData
= '<?xml version="1.0" encoding="Windows-1251"?>
<document>
<game>
    <title>Railroad Tycoon II Platinum</title>
    <genre>экономическая стратегия</genre>
    <designer>PopTop software</designer>
    <publisher>G.O.D. games</publisher>
    <year>2001</year>
</game>
<game>
    <title>Grand Prix 4</title>
    <genre>автосимулятор</genre>
    <designer>Geoff Crammond & Simergy</designer>
    <publisher>Infogrames Entertainment</publisher>
    <year>2002</year>
</game>
</document>'
;

$xslData = '<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="Windows-1251"/>

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="document">
    <html><head>
    <title>Игры</title>
    </head>
    <body>
    <h1>Игры</h1>
    <table cellpadding="2" cellspacing="2" border="1">
    <tr>
        <td>Название</td>
        <td>жанр</td>
        <td>год</td>
        <td>разработчик</td>
        <td>издатель</td>
    </tr>
        <xsl:apply-templates select="game"/>
    </table>
    </body></html>
</xsl:template>

<xsl:template match="game">
    <tr>
        <td><b><xsl:value-of select="title"/></b></td>
        <td><xsl:value-of select="genre"/></td>
        <td><xsl:value-of select="year"/></td>
        <td><xsl:value-of select="designer"/></td>
        <td><xsl:value-of select="publisher"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>'
;

$xh = xslt_create();

   
$arguments = array(
       
'/_xml' => $xmlData,
       
'/_xsl' => $xslData
   
);

   
$result = @xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
   

if (
$result)
    print (
$result);
else {
    print (
"There was an error that occurred in the XSL transformation...\n");
    print (
"\tError number: " . xslt_errno($xh) . "\n");
    print (
"\tError string: " . xslt_error($xh) . "\n");
    exit;
}

?>


Подобных примеров в Сети полно. Все они хорошо показывают, что XSL-трансформация в php работает, но после их прочтения остаётся неясным, зачем XSL нужен, скорее даже наоборот — почему XSL не нужен.

"Действительно", — подумает читатель, — "если данные лежат в базе, зачем городить огород, формируя сперва XML, а затем ещё преобразовывать через XSL? С тем же успехом это сделает класс HTML-шаблона."

После этого разочарованный программист напрочь теряет интерес к XSL и вешает на технологию ярлык "ненужная заумь".

Вам, уважаемые читатели, повезло найти такой замечательный сайт, как "php в деталях". Здесь вы прочитаете о том, что XSL может не только преобразовывать XML в HTML, но и то, как можно при помощи XSL облегчить работу с php-скриптами.

Начало работы


Приведённый выше пример, хоть и слишком прост, хорошо иллюстрирует, каким образом делается XSL-преобразование в php.

Чтобы этот код работал, нужно установить XSLT-процессор Sablotron. На виндовой машине это делается так:

1. положить iconv(-1.3).dll, expat.dll и sablot.dll в C:\windows\System (все файлы есть в стандартном дистрибутиве php)
2. открыть C:\windows\php.ini и в нём найти параметр extension_dir. Если значение параметра — "." или нечто вроде "./", исправить на, скажем, "f:\usr\local\php\extension" (или адрес директории, в которой у вас лежат/будут лежать расширения php). Теперь это будет директория расширений php.
3. положить в директорию расширений файл php_xslt.dll (это для php версии 4.2.x), либо php_sablot.dll (для версии 4.0.x)
4. в php.ini раскомментируйте строчку extension=php_xslt.dll (4.2.x) или extension=php_sablot.dll (4.0.x)

Теория


Использование XSLT позволяет отделить от php-скриптов работу по форматированию и представлению данных. Это не только уменьшение объёма кода, но и вынос большого количества логических конструкций (if, else, switch), а следовательно, облегчение работы по написанию и отладке программ. Смею утверждать, что тот, кто не пробовал работать с XSLT, не представляет себе, насколько php-кодирование облегчится.

Впрочем, не надо обольщаться: если у вас было несколько конструкций if ... else в php-скрипте, они, скорее всего, появятся в том же количестве в XSL-файле.

Теперь к примерам.

Вывод списков


Все усложнения, происходящие от необходимости выводить список в удобочитаемом виде, переносятся на плечи XSL. Пример #2. Список статей на сайте с подсветкой статьи, которую читают сейчас, чередование цвета в строках и нумерация списка.

XML:


<current-date>2002-05-30</current-date>

<list-
article date="2002-10-03">Ловля ошибок в PHP</list-article>
<list-
article date="2002-10-02">Живой проект и мёртвый журнал</list-article>
<list-
article date="2002-06-03">Работа с MySQL. Часть 7. Деревья</list-article>
<list-
article date="2002-05-30">Ручная сортировка в веб-интерфейсе</list-article>
<list-
article date="2002-05-29">Как поладить дизайнеру с программистом</list-article>
<list-
article date="2002-05-27">Relax this is PHP</list-article>


XSLT:


...
<
table>
<
xsl:apply-templates select="list-article"/>
</
table>
...

<
xsl:template match="list-article">
    <
tr>
    <
xsl:if test="position() mod 2 = 1">
        <
xsl:attribute name="bgcolor">#cccccc</xsl:attribute>
   
</xsl:if>
    <
td>
    <
xsl:value-of select="position()">
    <
a href="/{@date}.htm"><xsl:value-of select="."/></a>
    <
xsl:if test="@date = .. /current-date">&nbsp;&lt;</xsl:if>
    </
td>
    </
tr>
</
xsl:template>


Произвольная разметка


Переводя на XML сайт с текстами (как этот), естественно хотеть сделать собственную разметку статей. Например, в контейнером important выделять очень важные места и иметь возможность выделять их не обязательно жирным шрифтом, но, может быть, цветом, CSS-стилем. Или писать цитаты как <quote>текст цитаты<quote> и иметь возможность менять стиль их оформления вместе с дизайном сайта.

Медленно продвигаясь от самого простого первого примера, многие натыкаются на эту проблему и не могут найти решения. Ведь если выделить абзац в тег <para> и делать для него шаблон, на первый взгляд, существуют три способа вывода содержимого:

1. тег xsl:value-of выводит текст, но удаляет все теги в абзаце
2 .тег xsl:copy-of выводит копию всего содержимого (без возможности применять шаблоны к детям — внутренним тегам) и самого контейнера <para>...</para> (что не очень красиво в HTML).
3. наконец, xsl:apply-templates применит шаблоны к детям, но пропустит текст

Проблема кажется безвыходной, но решение есть. Я использую "магические" шаблоны, которые выводят и текст и теги в нём со всеми атрибутами и без изменений. Пример #3:

XML:


<text>
    <
para>Данный пример использует <strong>магические шаблоны</strong>
для разбора произвольной разметки. Это позволяет избежать таких жалоб:
    </
para>
    <
quote>Люди, памажите сами мы не местные! Не могу вывести теги в тексте
при помощи value
-of!
    </
quote>
    <
hr/>
    <
strong>Запомните эти шаблоны раз и навсегда!</strong>
    <
para>Тогда вы сможете обрабатывать <u>любой</u> <a href="http://www.txt.ru">текст</a>
Почти любой.
    </
para>
</
text>


XSLT:


<xsl:template match="text"><xsl:apply-templates/></xsl:template>

<
xsl:template match="strong">
    <
font color="#cc0000"><b><xsl:apply-templates/></b></font>
</
xsl:template>

<!--
три магических шаблона -->
<!--
1. общий -->
<
xsl:template match="*">
    <
xsl:copy>
        <
xsl:apply-templates select="@*" />
        <
xsl:apply-templates/>
    </
xsl:copy>
</
xsl:template>

<!--
2. для текста -->
<
xsl:template match="text()">
    <
xsl:value-of select="." disable-output-escaping="yes"/>
</
xsl:template>

<!--
3. для тегов и аттрибутов -->
<
xsl:template match="@*|node()">
    <
xsl:copy>
        <
xsl:apply-templates select="@*|node()"/>
    </
xsl:copy>
</
xsl:template>


Первым делом XSLT-процессор при вызове инструкции apply-templates ищет шаблон для каждого элемента. Для элемента strong шаблон есть, и именно в соответствии с ним такие элементы будут обработаны. Для гиперссылки шаблона нет, поэтому она будет выведена, как есть. Можно добавить в XSL шаблон и для ссылки, который бы выводил рядом с каждой текстовой ссылкой картинку для открытия её в новом окне:


<xsl:template match="a[@href]">
<
xsl:copy-of select="."/> <a href="{@href}"
target="_blank"><img src="/window.gif" width="15" height="15"
alt="открыть в новом окне"/></a>
</
xsl:template>

Категория: php | Добавил: freeone (10.05.2007) | Автор: Дмитрий Лебедев
Просмотров: 567 | Рейтинг: 0.0 |

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

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