При вызове функции PHP из таблицы стилей XSL в PHP 5.3 (и, возможно, ниже) у вас был полный доступ к ownerDocument
узлов XML, переданных в функцию.
<?php
$xml = <<<EOB
<allusers>
<user>
<uid>bob</uid>
</user>
</allusers>
EOB;
$xsl = <<<EOB
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:php="http://php.net/xsl">
<xsl:output method="text" encoding="utf-8" indent="yes"/>
<xsl:template match="allusers">
<xsl:for-each select="user">
<xsl:value-of
select="php:function('test', uid)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
EOB;
/**
* Test function
*
* @param DOMElement[] $node
* @return string
*/
function test(array $node)
{
$output = array(
'Document element: '.$node[0]->ownerDocument->documentElement->tagName,
'Node path: '.$node[0]->getNodePath(),
);
return implode(PHP_EOL, $output);
}
$xmldoc = DOMDocument::loadXML($xml);
$xsldoc = DOMDocument::loadXML($xsl);
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsldoc);
echo $proc->transformToXML($xmldoc);
Вывод этого скрипта в PHP 5.3:
Document element: allusers
Node path: /allusers/user/uid
Начиная с PHP 5.4 и выше, тот же скрипт приводит к:
Document element: allusers
Node path: /uid
Внутри функции PHP путь к узлу, по-видимому, ограничен «изолированным» DOM-документом с самим узлом в качестве documentElement
, Интересно, что вы все еще можете получить доступ к оригинальному документу через ownerDocument
но свойства вроде parentNode
и запросы XPath с использованием parent::*
или же ancestor::*
остановится на данном узле.
Есть ли способ восстановить полный доступ к ownerDocument
в PHP 5.4 и выше? Я не смог найти ничего в примечаниях к выпуску PHP, которые могли бы объяснить эту проблему.
РЕДАКТИРОВАТЬ 1: Интересно, что кажется возможным получить доступ к узлу nextSibling
изнутри функции PHP, но не ее previousSibling
,
Задача ещё не решена.
Других решений пока нет …