1

I am trying to include different source files (e.g. file1.xml and file2.xml) and have these includes resolved for an XSLT transformation using PHPs XSLTProcessor. This is my input:

source.xml

<?xml version="1.0" encoding="utf-8" ?>
<root xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file1.xml" />
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file2.xml" />
</root>

transform.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:transform>

transform.php

<?php
function transform($xml, $xsl) {
    global $debug;

    // XSLT Stylesheet laden
    $xslDom = new DOMDocument("1.0", "utf-8");
    $xslDom->load($xsl, LIBXML_XINCLUDE);

    // XML laden
    $xmlDom = new DOMDocument("1.0", "utf-8");
    $xmlDom->loadHTML($xml);                // loadHTML to handle possibly defective markup

    $xsl = new XsltProcessor();             // create XSLT processor
    $xsl->importStylesheet($xslDom);        // load stylesheet
    return $xsl->transformToXML($xmlDom);   // transformation returns XML
}
exit(transform("source.xml", "transform.xsl"));
?>

My desired output is

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <!-- transformed contents of file1.xml -->
    <!-- transformed contents of file2.xml -->
</root>

My current output is an exact copy of my source file:

<?xml version="1.0" encoding="utf-8" ?>
<root>
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file1.xml" />
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file2.xml" />
</root>
hielsnoppe
  • 2,819
  • 3
  • 31
  • 56
  • For you it might seem trivial, but I suggest you show the related PHP code as well. Then it's more clear how you setup the transformation and it should help to give better answers. – hakre Oct 01 '12 at 11:29
  • Yes, you're right. I will update it. – hielsnoppe Oct 01 '12 at 11:37
  • Ok. This might not be the issue, but are you sure that `utf8_decode` is right here? If you're concerned about the HTML doc + encoding, a related question is: http://stackoverflow.com/a/10834989/367456 (Just FYI). Looking further. – hakre Oct 01 '12 at 11:45
  • Thank you, I will check this again and remove it from my question. – hielsnoppe Oct 01 '12 at 11:48
  • Whatever you see fit, that was just some note. Can you clarify that you do not have this issue? https://bugs.php.net/bug.php?id=42609 (just for clarification, the includes are resolved, right?) – hakre Oct 01 '12 at 11:50
  • No they are not. This might well be the problem. – hielsnoppe Oct 01 '12 at 11:52
  • ah, okay. One step further I'd say. It was not that clear in the original version of your question. I'm out for lunch now, I might have the time to review your question this afternoon, it's an interesting one and if that is the bug, I'd say it should be possible to pre-process with XMLReader (part of the same PHP extension). – hakre Oct 01 '12 at 11:55
  • Sounds promising, I will have a look on that and then let you know. Thank you for your help and enjoy your meal! – hielsnoppe Oct 01 '12 at 11:58
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17396/discussion-between-hielsnoppe-and-hakre) – hielsnoppe Oct 01 '12 at 13:06

1 Answers1

1

It turned out, I just forgot one simple but important line in my PHP code. I had to call DOMDocument::xinclude to have the includes resolved before the transformation is done.

The full example:

<?php
function transform($xml, $xsl) {
    global $debug;

    // XSLT Stylesheet laden
    $xslDom = new DOMDocument("1.0", "utf-8");
    $xslDom->load($xsl, LIBXML_XINCLUDE);

    // XML laden
    $xmlDom = new DOMDocument("1.0", "utf-8");
    $xmlDom->load($xml);

    $xmlDom->xinclude();                    // IMPORTANT!

    $xsl = new XsltProcessor();
    $xsl->importStylesheet($xslDom);
    return $xsl->transformToXML($xmlDom);
}
exit(transform("source.xml", "transform.xsl"));
?>
hakre
  • 193,403
  • 52
  • 435
  • 836
hielsnoppe
  • 2,819
  • 3
  • 31
  • 56