Вы удаляете определение пространства имен для используемого пространства имен. В зависимости от порядка вызовов выполняются различные ремонтные работы. Ожидаемый способ удалить / изменить пространство имен - это пересечь и воссоздать узлы.
libxml выполняет некоторую оптимизацию и откат для определений пространства имен. Может случиться так, что он заменяет псевдоним пространства имен, если вы делаете «странные» вещи, и это может нарушить результат. На триггере находятся атрибуты с пространством имен. но без префикса. В отличие от элементов, атрибуты внутри пространства имен должны иметь префикс. Вот пример, который запускает префикс пространства имен по умолчанию:
$document = new DOMDocument();
$document->appendChild($document->createElementNS('urn:1', 'foo'));
// add attribute in namespace without prefix
$document->documentElement->setAttributeNS('urn:1', 'bar', 21);
echo $document->saveXML();
Выход:
<?xml version="1.0"?>
<foo xmlns="urn:1" xmlns:default="urn:1" default:bar="21"/>
Даже если вы используете префикс для атрибута, libxml распознает, что это то же пространство имен, что и пространство имен элемента по умолчанию, и пытается оптимизировать:
$document = new DOMDocument();
$document->appendChild($document->createElementNS('urn:1', 'foo'));
// add attribute in element namespace with prefix
$document->documentElement->setAttributeNS('urn:1', 'b:bar', 21);
echo $document->saveXML();
Мое правило - всегда использовать префикс для пространств имен, если мне нужно добавить атрибуты внутри этого пространства имен.
$document = new DOMDocument();
$document->appendChild($document->createElementNS('urn:1', 'b:foo'));
$document->documentElement->setAttributeNS('urn:1', 'b:bar', 21);
echo $document->saveXML();
Выход:
<?xml version="1.0"?>
<b:foo xmlns:b="urn:1" b:bar="21"/>
$new_node->removeAttributeNS("xmlns://www.abc.com", "");
сообщает DOM об удалении атрибута внутри пространства имен xmlns://www.abc.com
без имени. Однако xmlns=""
- это не атрибут, а определение пространства имен. Он использует тот же синтаксис и в некоторых случаях может быть изменен с использованием методов атрибута, но libxml может добавить его снова, потому что потомок или узел атрибута находится внутри пространства имен и требуется определение.
Рассматривая их как атрибуты xmlns="..."
отсутствует ни в одном пространстве имен, а определения пространств имен с префиксом, таким как xmlns:foo="..."
, находятся внутри зарезервированного пространства имен http://www.w3.org/2000/xmlns/
. imho Правильные вызовы для удаления определений пространства имен:
// xmlns="..."
$node->removeAttributeNS(NULL, 'xmlns');
// xmlns:prefix="..." - broken in PHP or libxml?
$node->removeAttributeNS('http://www.w3.org/2000/xmlns/', 'prefix');
Пример: * * тысяча тридцать-один
$document = new DOMDocument();
$document->appendChild($document->createElementNS('urn:1', 'b:foo'));
$document->documentElement->setAttributeNS(NULL, 'xmlns', 'urn:2');
$document->documentElement->setAttributeNS(
'http://www.w3.org/2000/xmlns/', 'xmlns:bar', 'urn:3'
);
echo $document->saveXML();
$document->documentElement->removeAttributeNS(NULL, 'xmlns');
echo $document->saveXML();
// for some reason that does not work
$document->documentElement->removeAttributeNS(
'http://www.w3.org/2000/xmlns/', 'bar'
);
echo $document->saveXML();
// but this works - weird
$document->documentElement->removeAttributeNS('urn:3', 'bar');
echo $document->saveXML();
Выход:
<?xml version="1.0"?>
<b:foo xmlns:b="urn:1" xmlns:bar="urn:3" xmlns="urn:2"/>
<?xml version="1.0"?>
<b:foo xmlns:b="urn:1" xmlns:bar="urn:3"/>
<?xml version="1.0"?>
<b:foo xmlns:b="urn:1" xmlns:bar="urn:3"/>
<?xml version="1.0"?>
<b:foo xmlns:b="urn:1"/>