Search code examples
phplibxml2

Two different outputs generated by SimpleXML on two different servers with the same PHP version


I have this code:

$feed = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:yandex="http://news.yandex.ru" xmlns:media="http://search.yahoo.com/mrss/" xmlns:turbo="http://turbo.yandex.ru" />', LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL);
$channel = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><channel></channel>', LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL);
$counter = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><yandex:analytics>test</yandex:analytics>', LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL);

$toDom = dom_import_simplexml($channel);
$fromDom = dom_import_simplexml($counter);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));

$toDom = dom_import_simplexml($feed);
$fromDom = dom_import_simplexml($channel);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->appendChild($dom->importNode(dom_import_simplexml($feed), true));
$dom->formatOutput = true;

var_dump($feed->saveXML());

Now, on one server the output is:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:yandex="http://news.yandex.ru" xmlns:media="http://search.yahoo.com/mrss/" xmlns:turbo="http://turbo.yandex.ru" version="2.0"><channel><yandex:analytics>test</yandex:analytics></channel></rss>

And on the second one the output is:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:yandex="http://news.yandex.ru" xmlns:media="http://search.yahoo.com/mrss/" xmlns:turbo="http://turbo.yandex.ru" version="2.0"><channel><analytics>test</analytics></channel></rss>

Both servers have the same PHP version: 7.1.30 the only xml related difference I noticed in two phpinfo() is that the first one has libxml2 2.9.9 and the other 2.7.6.

The older one is an old CentOS 6 system that cannot be upgraded for now unfortunately, and I'm not even sure if that's the libxml2's fault.

Now the problem is that I have a library that depends on the newer behavior.

Is it for sure related to libxml2 or not?

Can it be worked around somehow without throwing away the library depending on the first behavior?


Solution

  • The $counter XML is invalid, as you have it at the moment...

    $counter = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?>
             <yandex:analytics>test</yandex:analytics>', 
         LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL);
    

    The <yandex:analytics> is using a namespace which isn't defined in the XML itself.

    You should change this to define the namespace...

    <yandex:analytics xmlns:yandex="http://news.yandex.ru">test</yandex:analytics>
    

    or you can add it by creating the element manually before adding it...

    $fromDom = $toDom->ownerDocument->createElementNS("yandex", "yandex:analytics", "test");