How to work with DOMDocumentFragment in a XSLT with registerPHPFunctions?

dom, php, xslt

Solution

You can solve using the following XPath expression:

php:function('foo1')/node()

Now, is it a PHP bug? Or a libxml2 bug? It's difficult to say, because if you look at the specifications of XPath 1.0, you cannot find any reference to document fragments. The most similar thing is the root node, which is also the node used to represent a document.

I think the problem comes from PHP, when it constructs the node set to be returned. It should not return the whole document fragment node, but return a nodeset which is formed by its content.

However, I could be completely wrong, since I never used libxml2 and I don't know how it does work.

Problem

See sections "it works" and "it NOT works": is a bug of my code or a bug of DOMDocument-PHP implementation? If you not familiar with XSLT and registerPHPFunctions see this link for context and preparations. Suppose input by strings, ``` function XSL_transf($xml,$xsl) { $xmldoc = DOMDocument::loadXML($xml); $xsldoc = DOMDocument::loadXML($xsl); $proc = new XSLTProcessor(); $proc->registerPHPFunctions(); // here $proc->importStyleSheet($xsldoc); echo $proc->transformToXML($xmldoc); } $xml='<root/>'; //simplest $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"> ... HERE COPY/PASTE YOUR XSLT template ... </xsl:stylesheet> EOB; ``` it works The clause `<xsl:copy-of ... />` receives DOMElement, DOMDocument and (why not?) DOMDocumentFragment. So, if we have a PHP function that returns DOMDocument, we can use it. ``` function foo1() { $dom = DOMDocument::loadXML('<t> foo <tt val="123"/> bar </t>'); return $dom; } ``` Calling `foo1` into the template, ``` <xsl:template match="/"> PHP foo1()=<xsl:copy-of select="php:function('foo1')" /> </xsl:template> ``` RESULTS (you can use `XSL_transf($xml,$xsl)` to see): ``` <t> foo <tt val="123"/> bar </t> ``` it NOT works Changing the function above by ``` function foo1() { $dom = new DOMDocument; $tmp = $dom->createDocumentFragment(); $tmp->appendXML('<t> foo <tt val="123"/> bar </t> test'); return $tmp; } ``` the RESULT is empty. No error messages, but no result.

Original source