За последние 24 часа нас посетили 15004 программиста и 1765 роботов. Сейчас ищут 1623 программиста ...

PHP-код в XSLT

Тема в разделе "Прочие вопросы по PHP", создана пользователем html-программист, 20 июн 2012.

  1. html-программист

    html-программист Активный пользователь

    С нами с:
    10 фев 2012
    Сообщения:
    831
    Симпатии:
    4
    Адрес:
    Kiev
    Опять же возвращаясь к старой теме.
    Поцоны написали, что можно сделать так:
    Код (PHP):
    1. <xsl:text><![CDATA[<?php echo 123 ?>]]></xsl:text>
    но так можно сделать, если код xslt-шаблона находится в том-же файле, где и XSLT-процессор.
    У меня же все xslt-преобразования находятся в .xsl-файлах, поэтому тупо вываливает на страичку <?php echo 123 ?>
    Попробовал сделать такое:
    Код (PHP):
    1. AddHandler application/x-httpd-php .php .xsl
    но как и следовало ожидать, ничего не получилось.

    Какие еще могут быть варианты встроить php в xslt?

    Добавлено спустя 57 секунд:
    Хм, наверное можно сделать левый xml-файл, в котором и будет php-код на входе и xml на выходе, а его уже обрабатывать xslt-шаблонами
     
  2. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Код (Text):
    1. AddType application/x-httpd-php .xsl
    В начале файла не забыть
    Код (PHP):
    1. header('Content-type: text/xml'); 
    Тип добавить перед строкой
    Код (Text):
    1. Action application/x-httpd-php "путь к php"
     
  3. html-программист

    html-программист Активный пользователь

    С нами с:
    10 фев 2012
    Сообщения:
    831
    Симпатии:
    4
    Адрес:
    Kiev
    В начале какого файла? xsl-шаблона? Если в xsl-шаблон добавить хедер - XSLTProcessor выдаст ошибку
     
  4. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Не понятно. Обычно есть xml файлы, они в своём коде требуют файл преобразований xsl в теге
    Код (Text):
    1. <?xml-stylesheet href="style.xsl" type="text/xsl"?>
    Вот для xsl файла и настроить Апач, чтобы он воспринимал его, как php скрипт.

    В .htaccess или в httpd.conf вписать строчку
    Код (Text):
    1. AddType application/x-httpd-php .xsl
    Если xsl будет восприниматься, как php скрипт, то можно вписывать "<?php echo 123 ?>" хоть куда, или header('Content-type: text/xml'); или лучше header('Content-type: text/xsl');

    Проблема может возникнуть, если оставлять в xml файлах объявление
    Код (Text):
    1. <?xml version="1.0" encoding="utf-8"?>
    т.к. php будет сбивать с толку начало "<?". Нужно вывести объявление отдельно
    Код (PHP):
    1. <?php
    2. header('Content-type: text/xsl');
    3. echo '<?xml version="1.0" encoding="utf-8"?>';
    4. ?>
    5. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     
  5. html-программист

    html-программист Активный пользователь

    С нами с:
    10 фев 2012
    Сообщения:
    831
    Симпатии:
    4
    Адрес:
    Kiev
    Ок, тогда давай так.

    index.php:
    Код (PHP):
    1. <?php
    2. $doc = new DOMDocument();
    3. $doc->load('test.xml');
    4. $xsl= new DOMDocument();
    5. $xsl->load('test.xsl');
    6. $proc= new XSLTProcessor();
    7. $proc->importStyleSheet($xsl);
    8. echo $proc->transformToXML($doc);
    9. ?>
    test.xml
    Код (PHP):
    1. <?xml version="1.0" encoding="UTF-8"?> 
    2.    <udata>
    3.       <num>6</num>
    4.    </udata>
    test.xsl
    Код (PHP):
    1. <?xml version="1.0" encoding="UTF-8"?>
    2.    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    3.       <xsl:output method="html" encoding="utf-8" indent="yes"/>
    4.    
    5.       <xsl:template match="udata">
    6.          <xsl:call-template name="factorial">
    7.            <xsl:with-param name="n" select="num"/>
    8.          </xsl:call-template>
    9.       </xsl:template>
    10.       
    11.       <xsl:template name="factorial">
    12.          <xsl:param name="n"/>
    13.          <xsl:choose>
    14.             <xsl:when test="$n=0">1</xsl:when>
    15.             <xsl:otherwise>
    16.                <xsl:variable name="n-1">
    17.                   <xsl:call-template name="factorial">
    18.                      <xsl:with-param name="n" select="$n - 1"/>
    19.                   </xsl:call-template>
    20.                </xsl:variable>
    21.                <xsl:value-of select="$n * number($n-1)"/>
    22.             </xsl:otherwise>
    23.          </xsl:choose>
    24.       </xsl:template>
    25.       
    26.    </xsl:stylesheet>
    запускаем index.php, получаем в браузере 720

    Что мне в этом test.xsl дописать, чтобы можно было выполнить php-код? Вот хотя-бы тот-же session_start(); например

    Добавлено спустя 13 минут 59 секунд:
    Если же мы добавим в наш test.xsl вот тот хедер, то получим что-то типа этого:
    Код (PHP):
    1. Warning: DOMDocument::load() [domdocument.load]: Start tag expected, '<' not found in
    Поскольку test.xsl уже не валидный xml-файл

    ну и в том-же духе дальше:
    Код (PHP):
    1. Warning: XSLTProcessor::importStylesheet() [xsltprocessor.importstylesheet]: compilation error in
    Код (PHP):
    1. Warning: XSLTProcessor::importStylesheet() [xsltprocessor.importstylesheet]: xsltParseStylesheetProcess : empty stylesheet in
    Код (PHP):
    1. Warning: XSLTProcessor::transformToXml() [xsltprocessor.transformtoxml]: No stylesheet associated to this object in
     
  6. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Мда, я тебя не правильно понял. Никогда не использовал XSLTProcessor, т.к. считал, что загружать им сервер не стоит. Делал вывод отдельно сгенерированных xml и xsl, полагаясь на браузер пользователя.

    Т.к. нужно всё это преобразовать на сервере, можно так:
    index.php
    Код (PHP):
    1. <?php
    2. //index.php//использование XSLTProcessor
    3. include('test.xml');//парсинг/выполнение/присоединение переменных
    4. $doc=new DOMDocument();
    5. $doc->loadXML($docF);//вместо ->load(файл)
    6.  
    7. $xsl= new DOMDocument();
    8. include('test.xsl');
    9. $xsl->loadXML($xslF);//вместо ->load(файл)
    10.  
    11. $proc= new XSLTProcessor();
    12. $proc->importStyleSheet($xsl);
    13. echo $proc->transformToXML($doc);
    14. ?>
    test.xml
    Код (PHP):
    1. <?php
    2. echo '<?xml version="1.0" encoding="UTF-8"?>',"\n";
    3. //и любой другой php код...
    4. ?>
    5. <udata>
    6. <num>6</num>
    7. </udata>
    В test.xsl то же самое сделать, вывести '<?xml version="1.0" encoding="UTF-8"?>' через echo.


    В этом случае, если не придется вызывать xml и xsl из браузера, то не нужно добавлять в .htaccess
    Код (Text):
    1. AddType application/x-httpd-php .xsl
    2. AddType application/x-httpd-php .xml
     
  7. html-программист

    html-программист Активный пользователь

    С нами с:
    10 фев 2012
    Сообщения:
    831
    Симпатии:
    4
    Адрес:
    Kiev
    Да тут наверное можно было в index.php загрузить xsl через file_get_content и отдать его XSLT-процессору через loadXML а не через load., и даже не пришлось бы городить htaccess - xsl-шаблон бы находился в php-файле.
    Но проблема в другом
    На сервере я ничего сделать не могу, кроме как править XSLT-шаблоны. Это движок UMI.CMS. Понадобилось на сайт добавить нестандартный блок, который невозможно сделать средствами движка. Можно это реализовать через макросы, но документация по написанию макросов очень скудная. Сами же файлы движка выглядят примерно так:

    Код (PHP):
    1. $v8b1dc169bf460ee884fceef66c6607d6 = cmsController::getInstance();$v72ee76c5c29383b7c9f9225c1fa4d10b = $v8b1dc169bf460ee884fceef66c6607d6->getCurrentDomain()->getId();$v100664c6e2c0333b19a729f2f3ddb7dd = CURRENT_WORKING_DIR . "/sys-temp/sitemap/{$v72ee76c5c29383b7c9f9225c1fa4d10b}/";$v736007832d2167baaae763fd3a3f3cf1 = dir($v100664c6e2c0333b19a729f2f3ddb7dd);while (false !== ($v8c7dd922ad47494fc02c388e12c00eac = $v736007832d2167baaae763fd3a3f3cf1->read())) {if(is_file($v100664c6e2c0333b19a729f2f3ddb7dd . $v8c7dd922ad47494fc02c388e12c00eac)) readfile($v100664c6e2c0333b19a729f2f3ddb7dd . $v8c7dd922ad47494fc02c388e12c00eac);}$v736007832d2167baaae763fd3a3f3cf1->close();echo '</urlset>';
    2. и т.д. 
    таких вот файлов еще несколько тысяч и все это в одну строчку