Ответ 1
Что-то, что работает для меня, - это вернуть экземпляр DOMDocumentFragment
вместо массива. Поэтому, чтобы попробовать это на вашем примере, я сохранил ваш ввод как foo.xml
. Затем я сделал foo.xslt
следующим образом:
<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:php="http://php.net/xsl">
<xsl:template match="/">
<xsl:call-template name="listing" />
</xsl:template>
<xsl:template match="name">
<bar> <xsl:value-of select="text()" /> </bar>
</xsl:template>
<xsl:template name="listing">
<foo>
<xsl:for-each select="php:function('all_but_first', /p/name)">
<xsl:apply-templates />
</xsl:for-each>
</foo>
</xsl:template>
</xsl:stylesheet>
(Это скорее всего ваш пример с оберткой xsl:stylesheet
, чтобы вызвать его.) И реальное сердце, foo.php
:
<?php
function all_but_first($nodes) {
if (($nodes == null) || (count($nodes) == 0)) {
return ''; // Not sure what the right "nothing" return value is
}
$returnValue = $nodes[0]->ownerDocument->createDocumentFragment();
array_shift($nodes);
shuffle($nodes);
foreach ($nodes as $node) {
$returnValue->appendChild($node);
}
return $returnValue;
};
$xslDoc = new SimpleXMLElement('./foo.xslt', 0, true);
$xmlDoc = new SimpleXMLElement('./foo.xml', 0, true);
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStylesheet($xslDoc);
$buffer = $proc->transformToXML($xmlDoc);
echo $buffer;
?>
Важной частью является вызов ownerDocument->createDocumentFragment()
, чтобы объект возвращался из функции.