开发者

Multiple XML/XSLT files in PHP, transform one with XSLT and add others but process it first with PHP

I am processing XML files transformations with XSLT in PHP correctly. Actually I use this code:

$xml = new DOMDocument;
$xml->LoadXML($xml_contents);

$xsl = new DOMDocument;
$xsl->load($xsl_file);

$proc = new XSLTProcesoor;
$proc->importStyleSheet($xsl);

echo $proc->transformToXml($xml);

$xml_contents is the XML processed with PHP, this is done by including the XML file first and then assigning $xml_contents = ob_get_contents(); ob_end_clean();. This forces to process the PHP code on the XML, and it works perfectly.

My problem is that I use more than one XML file and this XML files has PHP code on it that need to be processed AND have a XSLT file associated to process the data. Actually I开发者_开发百科'm including this files in XSLT with the next code:

<!-- First I add the XML file -->
<xsl:param name="menu" select="document('menu.xml')" />

<!-- Next I add the transformations for menu.xml file -->
<xsl:include href="menu.xsl" />

<!-- Finally, I process it on the actual ("parent") XML -->
<xsl:apply-templates select="$menu/menu" />

My questiion is how I can handle this. I need to add mutiple XML(+XSLT) files to my first XML file that will containt PHP so it needs to be processed.

Thank you in advance!


2 solutions, maybe one of them will be ok.

Not tested, but you can implement a custom stream in PHP.

<?php

// define your custom stream, should process xslt
class CustomStream extends streamWrapper {
    // http://www.php.net/manual/en/class.streamwrapper.php
}

// declare your custom stream
stream_wrapper_register('extra', 'CustomStream');

// then load your preprocessed on the fly in your example.xsl
$xml_contents = <<<EOF
...
<xsl:param name="menu" select="document('extra://menu.xml')" />
EOF;


?>

Solution n°2, register php functions in your xslt, and play with it :

<?php
// declare your function
// see http://www.php.net/manual/fr/xsltprocessor.registerphpfunctions.php
function resolve($xml_contents, $xsl_file=null) {
    $dom = new DomDocument;
    $dom->loadXML($xml_contents);
    if ($xsl == null) {
        return $dom;
    }

    $xsl = new DOMDocument;
    $xsl->load($xsl_file);

    $proc = new XSLTProcessor;

    $proc->registerPHPFunctions('resolve');
    $proc->importStyleSheet($xsl);

    return $proc->transformToDoc($xml_contents);
}


// then handle your master xsl
$xsl_contents = <<<EOF
...
<xsl:param name="menu" select="php:function('resolve', 'menu.xml', 'menu.xsl')" />
EOF;

$dom = new DomDocument;
$dom->loadXML($xml_contents);

$xsl = new DOMDocument;
$xsl->loadXML($xsl_contents);

$proc = new XSLTProcessor;

$proc->registerPHPFunctions('resolve');
$proc->importStyleSheet($xsl);

return $proc->transformToDoc($xml_contents);

?>


I'm not sure what you mean by "XML file that will contain PHP", but I'm guessing that you need php to interfere with the XSLT processing after it's started. Otherwise you'd be using PHP to manipulate the source XML before any XSLT transformation is run.

There's php functionality that allows you to run arbitrary php inside XSLT stylesheet during processing, although it is an extension of the standard XSLT.

There's more info and examples.

EDIT:

On the second thought, if you simply need to specify what XML to load without hardcoding it into XSLT, document() function may use source XML nodes for names of the files to load. So you just generate names in XML, and then have document() read them for further reference in the template.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜