[SimpleXMLElement::]getNamespaces() returns an array of all the namespaces from the document
No, that is SimpleXMLElement::getDocNamespaces().
SimpleXMLElement::getNamespaces() returns the namespaces of the element.
The first key/value of the returned array is the namespace-prefix/namespace-uri of the element itself (if it has one which we assume in this case1), all following are additional ones, e.g. of element attributes.
Example:
<?php declare(strict_types=1);
$sx = simplexml_load_string(<<<XML
<x xmlns:aed="http://aecommerce.org/schema" xmlns:edi='http://ecommerce.org/schema'>
<!-- the 'price' element's namespace is http://ecommerce.org/schema -->
<edi:price units='Euro' aed:more="test">
32.18
</edi:price>
</x>
XML, null, 0, 'http://ecommerce.org/schema');
// XML example from https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using
var_dump($sx->price->getNamespaces());
/usr/bin/php8.1 -dzend.assertions=1 -dassert.exception=1 /home/hakre/sxml-namespace.php
array(2) {
["edi"]=>
string(27) "http://ecommerce.org/schema"
["aed"]=>
string(28) "http://aecommerce.org/schema"
}
If you leave out the attribute in the XML, the array entry is gone:
<?php declare(strict_types=1);
$sx = simplexml_load_string(<<<XML
<x xmlns:aed="http://aecommerce.org/schema" xmlns:edi='http://ecommerce.org/schema'>
<!-- the 'price' element's namespace is http://ecommerce.org/schema -->
<edi:price units='Euro'>
32.18
</edi:price>
</x>
XML, null, 0, 'http://ecommerce.org/schema');
// XML example from https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-using
var_dump($sx->price->getNamespaces());
var_dump($sx->price->getDocNamespaces());
/usr/bin/php8.1 -dzend.assertions=1 -dassert.exception=1 /home/hakre/sxml-namespace.php
array(1) {
["edi"]=>
string(27) "http://ecommerce.org/schema"
}
array(2) {
["aed"]=>
string(28) "http://aecommerce.org/schema"
["edi"]=>
string(27) "http://ecommerce.org/schema"
}
1 It would be otherwise in the default namespace.