Здравствуйте.
Давно не работал с XSL, особенно, с его PHP-реализаций.
Возникла задача преобразовывать некий документ, основываясь на динамических данных, поступаемых извне в формате ассоциативного массива php.
Вот такой XSL-стиль я жду на выходе:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="from">
<to>
<xsl:apply-templates/>
</to>
</xsl:template>
</xsl:stylesheet>
Примерно так я создаю экземпляр DOMDocument, который в будущем будет использоваться для преобразования:
$xsldoc = new DOMDocument('1.0', 'utf-8');
$root = $xsldoc->createElementNS('http://www.w3.org/1999/XSL/Transform', 'xsl:stylesheet');
$first_tpl = $xsldoc->createElement('xsl:template');
$first_tpl->setAttribute('match', 'node()|@*');
$copy = $xsldoc->createElement('xsl:copy');
$inner = $xsldoc->createElement('xsl:apply-templates');
$inner->setAttribute('select', 'node()|@*');
$copy->appendChild($inner);
$first_tpl->appendChild($copy);
$root->appendChild($first_tpl);
$root->setAttribute('version', '1.0');
$xsldoc->appendChild($root);
// и еще несколько строк генерации дерева, опущу их для краткости
Код выше примерный, но главная его особенность в том, что он генерирует XSL-стиль абсолютно идентичный эталонному.
Далее я создаю экземпляр XSLTProcessor и пытаюсь трансформировать исходный документ:
$proc = new XSLTProcessor();
$proc->importStylesheet($xsldoc);
var_dump($proc->transformToXML($this->document));
После чего я получаю warning следующего содержания:
PHP Warning: XSLTProcessor::importStylesheet(): Found a top-level element xsl:template with null namespace URI
Но если я сдамплю сгенерированный XSL-документ в XML и создам новый экземпляр DOMDocument, в который загружу этот полученный XML, то всё будет в порядке и исходное преобразование пройдет:
$proc = new XSLTProcessor();
$n = new DOMDocument();
$n->loadXML($xsldoc->saveXML());
$proc->importStylesheet($xsldoc);
var_dump($proc->transformToXML($this->document)); // здесь всё отлично
В последних строчках я добился результата ценой некоторого оверхеда, но причину ошибки я так и не понял. Не могло бы уважаемое сообщество указать мне на неё?
Спасибо.