PHP5: аналог xslt_set_base()

  • Автор темы Bananan
  • Дата начала

Bananan

Guest
PHP5: аналог xslt_set_base()

Привет!

В XSLT API PHP4 для Саблотрона была замеччательная функция xslt_set_base (http://de.php.net/manual/en/function.xslt-set-base.php)

Как всем нам известно, в PHP5 использщуется новый API и новая библиотека libxslt.
До сих пор я не нашел способа эмулировать xslt_set_base(), чтобы задать базовый URI для всех моих трансляций.

Возможно кто-то уже знает рецепт или альтернативу?


С уважением.
 

chameleon

Новичок
для внешних включений в качестве базового используется либо URL документа либо шаблона.
 

slach

Новичок
chameleonn
а что такое URL документа, когда он создается с нуля в виде DOMXML объекта??

и что такое URL шаблона, когда в него просто импортируется опять же собраный из различных кусков DOMXML объект ?
 

slach

Новичок
Автору вопроса
в общем пока никаких аналогов нет
и скорее всего не предвидится...
 

Bananan

Guest
Господа, мне кажется что отсутствие Base URI очень плохо.

1) Допустим у меня есть масса трансляций по числу страниц сайта.

2) Каждая трансляция импортирует в себя шаблон page.xsl, в котором описываются общий шаблон страницы (header/footer)
Здесь можно указать для каждой трансляции относительный путь к page.xsl

Проблемы начинаются далее.


3) В свою очередь page.xsl подключает ряд стандартных xsl
библиотек,а также xml фалов (например карту сайта). Все это через import и document.


Получается. что в PHP5 единственным решением в данном случае будет подключение всего добра из пункта три через HTTP?

А не слишком ли накладно получается?


Может быть у вас есть соображения по этому поводу? Что-то в консерватории поправить? :)

-~{}~ 09.12.04 13:23:

Автор оригинала: slach
Автору вопроса
в общем пока никаких аналогов нет
и скорее всего не предвидится...
Возможно есть какая-то аргументация у разработчиков по поводу "не предвидится"? На чем основано такое опасение?


См. описание проблемы выше.
 

chameleon

Новичок
Каждая трансляция импортирует в себя шаблон page.xsl, в котором описываются общий шаблон страницы (header/footer)
Здесь можно указать для каждой трансляции относительный путь к page.xsl
неправильная организация - по-нормальному специфический шаблон импортирует библиотечный, а не наоборот.
Получается. что в PHP5 единственным решением в данном случае будет подключение всего добра из пункта три через HTTP?
почему именно HTTP? почему не абсолютные пути от корня сервера?
 

Bananan

Guest
Автор оригинала: chameleon
неправильная организация - по-нормальному специфический шаблон импортирует библиотечный, а не наоборот.
У меня специфический шаблон импортирует ОДИН общий (библиотечный) шаблон (prepend/page/как хотите). А тот в свою очередь подключает еще несколько.

Никакого противоречия с Вами не вижу. Или вы предлагаете делать на каждом специфическом шаблоне по 10 одинаковых импортов библиотек?
А когда надо добавить надо будет добавить 11-й?



почему именно HTTP? почему не абсолютные пути от корня сервера?
Потому что в таком случпае неудобно разрабатывать.
Если прототип лежит на локальной машине по Windows - абсолютный путь один. Сама система лежит на сервере UNIX абсолютный путь другой. Если же определить этот путь в одном библиотечном шаблоне как переменную его придется таскать по другим импортируемым шаблонам, чтотоже не очень удобно.

-~{}~ 19.01.05 13:00:

Господа, прошло больше месяца, а ответов в инете не прибавилось. только аналогичные вопросы.

Все ищут аналог и не могут найти.


Неужели разработчикам по барабану?
 

chameleon

Новичок
ну давайте еще раз :)..
ситуация такова что specific_page.xsl, которая импортирует common_page.xsl, которая импортирует more_common_page.xsl...
importы в specific_page.xsl расшифровываются относительно нее же, а importы в common_page.xsl относительно common_page.xsl так ведь? ну перенесли more_common_page.xsl в другое место, поправили ссылку в common_page.xsl и забыли.

-~{}~ 19.01.05 19:47:

или я гоню под вечер? :)...
 

Bananan

Guest
"а importы в common_page.xsl относительно common_page.xsl "

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

В любом случае проверю еще раз.


Главная проблема в другом. Допустим я использую common_page.xsl как стартовую трансляцию вдля трех страниц на разных уровнях. Раньше это не было проблемой.

Теперь я вынужден паковать все в искуственные wrapper-ы - xsl-файлы единственная задача которых, подключить common_page.xsl c правильным путем.

Допустим xsl с правилами для оформления статьи. Статей у меня 100. В итоге 100 specific_page.xsl?

Или _я_ гоню под вечер? :)
 

chameleon

Новичок
В этом не уверен. По-моему нет.
A relative URI is resolved relative to the base URI of the xsl:include element
поскольку процессор сначалапреобразует все включения в один общий файл
как это может влиять на то, как процессор должен расшифоровывать относительные ссылки? имхо, никак.
Допустим я использую common_page.xsl как стартовую трансляцию вдля трех страниц на разных уровнях....
это проблема, если ссылка импортирования расшифровывается относительно документа, а это не так. Относительно документа в некоторых случаях могут расшифоровываться аргументы ф-ции document()...
P.S. или я гоню под _утро_? ;)..
 

Bananan

Guest
Автор оригинала: chameleon
это проблема, если ссылка импортирования расшифровывается относительно документа, а это не так. Относительно документа в некоторых случаях могут расшифоровываться аргументы ф-ции document()...
P.S. или я гоню под _утро_? ;)..
Ну как же не так? Давайте проведем эксперимент PHP5 + XSLT?

1) ДЕлаем PHP Файлы:
/index.php
/level2/index.php

2) Оба берут /index.xml
и применяют к нему /index.xsl


3) внутри index.xsl вызов import для lib.xsl

lib.xsl кладем тоже в корень.


Одна из трансляций точно не будет работать. (/index.php или/level2/index.php) потому что путь для importa им ндоуказать _разный_.



Т.о. придется делать два файлика index.xsl


Или мы все гоним? :)))
 

slach

Новичок
костыль конечно, но

<xsl:import href="file:///usr/local/apache/htdocs/lib.xsl">

соответсвенно href= надо где то в самом PHP Высталять например с помощью buffering output
 

Bananan

Guest
Автор оригинала: slach
костыль конечно, но

<xsl:import href="file:///usr/local/apache/htdocs/lib.xsl">

соответсвенно href= надо где то в самом PHP Высталять например с помощью buffering output
Да, я так тоже думал.

Отдам полцарства и дочку сисадмина впридачу, если мне расскажут, как динамически генерировать href в import.

С помощью средств XSL это имхо невозможно.


Единственный вариант который мне приходит в голову - парсить xsl еще раз перед применением и подменять пути на нужные.

Страшное дело. Это имелось ввиду под output buffering?
 

Bananan

Guest
Автор оригинала: chameleon
извините, но вы проверяли? давайте уже код в студию. Я в импортах ничего не меняю и все работает. [PHP_5.0.4-dev]
Ок. Код будет завтра или сегодня вечером. Сегодня не получится :(


Может я действительно сошел с ума. :)
 

chameleon

Новичок
структура:

1. /import.php
PHP:
<?php
$xml = DOMDocument::load('test.xml');
$xslt_doc = DOMDocument::load('test1.xsl');
$proc = new xsltprocessor();
$xslt_doc = $proc->importStylesheet($xslt_doc);
$xml = $proc->transformToDoc($xml);
header('Content-type: application/xml');
echo $xml->saveXML();
?>
2. /test.xml
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<root>
    <test>123</test>
</root>
3. /test1.xsl
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="ws/test2.xsl"/>
</xsl:stylesheet>
4. /ws/import.php
PHP:
<?php
$xml = DOMDocument::load('../test.xml');
$xslt_doc = DOMDocument::load('../test1.xsl');
$proc = new xsltprocessor();
$xslt_doc = $proc->importStylesheet($xslt_doc);
$xml = $proc->transformToDoc($xml);
header('Content-type: application/xml');
echo $xml->saveXML();
?>
5. /ws/test2.xsl
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<u><xsl:apply-templates /></u>
</xsl:template>
</xsl:stylesheet>
запускем:
http://example.com/import.php
http://example.com/ws/import.php
результат один и тот же:
<?xml version="1.0"?><u>123</u>
 

Bananan

Guest
Мы друг друга недопоняли. Смотрите, как я переделал ваш пример:

структура:

0. /_shared/shared.xsl
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
...
</xsl:stylesheet>
1. /import.php
PHP:
<?php
$xml = DOMDocument::load('test.xml');
$xslt_doc = DOMDocument::load('test1.xsl');
$proc = new xsltprocessor();
$xslt_doc = $proc->importStylesheet($xslt_doc);
$xml = $proc->transformToDoc($xml);
header('Content-type: application/xml');
echo $xml->saveXML();
?>
2. /test.xml
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<root>
    <test>123</test>
</root>
3. /test1.xsl
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="_shared/shared.xsl"/>
<u><xsl:apply-templates /></u> 
</xsl:stylesheet>
4. /ws/import.php
PHP:
<?php
$xml = DOMDocument::load('../test.xml');
$xslt_doc = DOMDocument::load('../test1.xsl');
$proc = new xsltprocessor();
$xslt_doc = $proc->importStylesheet($xslt_doc);
$xml = $proc->transformToDoc($xml);
header('Content-type: application/xml');
echo $xml->saveXML();
?>
5. /ws/test2.xsl
<?xml version="1.0" encoding="UTF-8"?>
PHP:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="_shared/shared.xsl"/>

<xsl:template match="/">
<u><xsl:apply-templates /></u>
</xsl:template>
</xsl:stylesheet>
запускем:
http://example.com/import.php
http://example.com/ws/import.php


результат ?
 

Bananan

Guest
Автор оригинала: chameleon
ессно тот же...от того, что вы выкинули test2.xsl и импортируете свой шаблон ничего не изменится...
Вообще-то я импортирую его и там и там.

и в
test1.xsl
test2.xsl

на то он и shared

У вас точно заработало?

-~{}~ 20.01.05 19:32:

У меня точно не работает когда трансляции import.php лежат на _разных уровнях_ (как в вашем примере), а сами xsl файлы на _одном_ уровне.(в одном каталоге).

/test1.xsl
/test2.xsl
 
Сверху