K
K
Konstantin2014-10-31 05:29:26
PHP
Konstantin, 2014-10-31 05:29:26

Why can't XSL transform be performed on a dynamically constructed DOMDocument instance?

Hello.
Haven't worked with XSL for a long time, especially with its PHP implementations.
There was a task to convert a certain document, based on dynamic data coming from outside in the format of an associative php array.
This is the XSL style I expect as output:

<?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>

Something like this, I create a DOMDocument instance, which will be used for transformation in the future:
$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);
// и еще несколько строк генерации дерева, опущу их для краткости

The code above is exemplary, but its main feature is that it generates an XSL style that is absolutely identical to the reference one.
Next, I create an XSLTProcessor instance and try to transform the original document:
$proc = new XSLTProcessor();
$proc->importStylesheet($xsldoc);
var_dump($proc->transformToXML($this->document));

Then I get a warning with the following content:
PHP Warning:  XSLTProcessor::importStylesheet(): Found a top-level element xsl:template with null namespace URI

But if I dump the generated XSL document into XML and create a new DOMDocument instance into which I load this resulting XML, then everything will be fine and the original transformation will pass:
$proc = new XSLTProcessor();
$n = new DOMDocument();
$n->loadXML($xsldoc->saveXML());
$proc->importStylesheet($xsldoc);
var_dump($proc->transformToXML($this->document)); // здесь всё отлично

In the last lines, I achieved the result at the cost of some overhead, but I still did not understand the cause of the error. Could the respected community point me to it?
Thank you.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question