Closed
Description
Description
The following code:
<?php
$doc = new DOMDocument();
$doc->loadXML(
<<<XML
<container xmlns="http://symfony.com/schema/dic/services">
CHILDREN
</container>
XML
);
//
// Remove xmlns Attribute + Validate it is actually gone.
// As you can see, it still remembers a 'xmlns' DOMNameSpaceNode with an empty namespaceURI (which basically is invalid!)
// The same happens when you prefix the declaration. For example xmlns:prefixed="...."
//
$doc->documentElement->removeAttributeNS('http://symfony.com/schema/dic/services', '');
var_dump($doc->documentElement->getAttributeNode('xmlns'));
$namespaces = [...(new DOMXPath($doc))->query('./namespace::*', $doc->documentElement)];
//
// Yet when saving the XML : there is no problem, the namespaces are gone.
//
echo $doc->saveXML();
var_dump($namespaces);
//
// However ...
// When importing the node in a new document, it gets prefixed by <default:container ...> without any xmlns:default declaration
//
$new = new DOMDocument();
$new->append(
$new->importNode($doc->documentElement, true)
);
echo $new->saveXML();
// Resulting in invalid XML obviously:
$previousErrorReporting = libxml_use_internal_errors(true);
libxml_clear_errors();
$parsedAgain = new DOMDocument();
$parsedAgain->loadXML($new->saveXML());
$errors = libxml_get_errors();
libxml_clear_errors();
libxml_use_internal_errors($previousErrorReporting);
var_dump($errors);
Resulted in this output:
object(DOMNameSpaceNode)#3 (8) {
["nodeName"]=>
string(5) "xmlns"
["nodeValue"]=>
NULL
["nodeType"]=>
int(18)
["prefix"]=>
string(0) ""
["localName"]=>
string(5) "xmlns"
["namespaceURI"]=>
NULL
["ownerDocument"]=>
string(22) "(object value omitted)"
["parentNode"]=>
string(22) "(object value omitted)"
}
<?xml version="1.0"?>
<container>
CHILDREN
</container>
array(2) {
[0]=>
object(DOMNameSpaceNode)#4 (8) {
["nodeName"]=>
string(9) "xmlns:xml"
["nodeValue"]=>
string(36) "http://www.w3.org/XML/1998/namespace"
["nodeType"]=>
int(18)
["prefix"]=>
string(3) "xml"
["localName"]=>
string(3) "xml"
["namespaceURI"]=>
string(36) "http://www.w3.org/XML/1998/namespace"
["ownerDocument"]=>
string(22) "(object value omitted)"
["parentNode"]=>
string(22) "(object value omitted)"
}
[1]=>
object(DOMNameSpaceNode)#5 (8) {
["nodeName"]=>
string(5) "xmlns"
["nodeValue"]=>
NULL
["nodeType"]=>
int(18)
["prefix"]=>
string(0) ""
["localName"]=>
string(5) "xmlns"
["namespaceURI"]=>
NULL
["ownerDocument"]=>
string(22) "(object value omitted)"
["parentNode"]=>
string(22) "(object value omitted)"
}
}
<?xml version="1.0"?>
<default:container>
CHILDREN
</default:container>
array(1) {
[0]=>
object(LibXMLError)#7 (6) {
["level"]=>
int(2)
["code"]=>
int(201)
["column"]=>
int(19)
["message"]=>
string(53) "Namespace prefix default on container is not defined
"
["file"]=>
string(0) ""
["line"]=>
int(2)
}
}
But I expected this output instead:
<default:container>
CHILDREN
</default:container>
Should be
<container>
CHILDREN
<container>
This namespace node should not be there, since it is invalid because there is a NULL namespaceURI:
object(DOMNameSpaceNode)#5 (8) {
["nodeName"]=>
string(5) "xmlns"
["nodeValue"]=>
NULL
["nodeType"]=>
int(18)
["prefix"]=>
string(0) ""
["localName"]=>
string(5) "xmlns"
["namespaceURI"]=>
NULL
["ownerDocument"]=>
string(22) "(object value omitted)"
["parentNode"]=>
string(22) "(object value omitted)"
}
More context:
- @nielsdos mentioned there was a related issue in libxml : https://gitlab.gnome.org/GNOME/libxml2/-/issues/613
PHP Version
PHP >8 >7 >??
Operating System
No response