Методы, поддерживающие пространство имен (например, DOMDocument::createElementNS()
), создают узел в предоставленном пространстве имен.Они устанавливают свойство namespaceURI
, другие методы - нет.
Таким образом, узел не находится в ожидаемом пространстве имен, а XML не соответствует схеме.Вот небольшая демонстрация:
$document = new \DOMDocument();
$foo = $document->appendChild($document->createElementNS('urn:foo', 'f:foo'));
$foo->appendChild($document->createElementNS('urn:foo', 'f:bar'));
$foo->appendChild($document->createElement('f:bar'));
echo "after create\n";
foreach ($document->documentElement->childNodes as $bar) {
echo '{'.$bar->namespaceURI.'}'.$bar->localName, "\n";
}
Вывод:
after create
{urn:foo}bar
{}f:bar
Используя методы без учета пространства имен, вы можете создать DOM, который будет сериализован в одну и ту же строку XML - даже если узелбыл создан без пространства имен.
echo $xml = $document->saveXML();
Вывод:
<?xml version="1.0"?>
<f:foo xmlns:f="urn:foo"><f:bar/><f:bar/></f:foo>
Теперь, если этот документ загружен, анализатор разрешит пространства имен, и оба узла bar
находятся в ожидаемом пространстве имен.
$document->loadXML($xml);
echo "after load\n";
foreach ($document->documentElement->childNodes as $bar) {
echo '{'.$bar->namespaceURI.'}'.$bar->localName, "\n";
}
Вывод:
after load
{urn:foo}bar
{urn:foo}bar
Я предлагаю использовать методы, учитывающие пространство имен, если вы создаете XML с пространствами имен.Что касается того, почему узел не может наследовать пространство имен родителя.Он существует до этого (после создания) и получает родителя, только если вы добавляете / вставляете его.