Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cloneNode inconsistent with namespaces - cross environments?

Tags:

dom

php

xpath

When attempting to clone a DOMNode object (DOMNode::cloneNode) I am experiencing inconsistencies running it across different environments, specifically with the clone failing to copy the namespace when I print the nodeName property, e.g.

$cloneNode = $origNode->cloneNode(true);
echo("old node name = " . $origNode->nodeName);
echo("new node name = " . $cloneNode->nodeName);

result (local - mac os)
"old node name = namespace:Hello"
"new node name = namespace:Hello"

result (local - centos):
"old node name = namespace:Hello"
"new node name = Hello"

I register the namespace with DOMXPath::registerNamespace prior to doing anything with nodes.

Update

I've found the offending line ($origNode->parentNode->removeChild( $origNode );) that when removed causes the clone to work as expected, regardless. Keeping said line in however still yields different results cross environment. An example:

<?php

$string = '<?xml version="1.0" encoding="UTF-8"?>
<ns:Root xmlns:ns="http://google.com/">
    <ns:Hello>
        <ns:World/>
    </ns:Hello>
</ns:Root>';

$dom = new \DOMDocument();
$dom->loadXML($string);


$xpath = new \DOMXPath($dom);
$rootNamespace = $dom->documentElement->lookupNamespaceUri('ns');
$xpath->registerNamespace('ns', $rootNamespace);


$parentNode = $xpath->query('//ns:Hello')->item( 0 );
$origNode = $xpath->query('//ns:World')->item( 0 );
$origNode->parentNode->removeChild($origNode);

$newNode = $origNode->cloneNode( true );

echo("old node name = " . $origNode->nodeName) . PHP_EOL;
echo("new node name = " . $newNode->nodeName) . PHP_EOL;

?>
like image 687
canisay Avatar asked Nov 12 '22 04:11

canisay


1 Answers

Resolved - the different behavior was the result of different versions of libxml (20706 vs 20708). After updating the centos box to 20708 the namespace persisted as expected.

like image 57
canisay Avatar answered Nov 14 '22 21:11

canisay