DOMNode::removeChild

(PHP 5)

DOMNode::removeChild Удаляет дочерний узел из списка потомков

Описание

public DOMNode DOMNode::removeChild ( DOMNode $oldnode )

Эта функция удаляет дочерний узел из списка потомков.

Список параметров

oldnode

Удаляемый дочерний узел.

Возвращаемые значения

Функция возращает удаляемый дочерний узел, если он может быть удален.

Ошибки

DOM_NO_MODIFICATION_ALLOWED_ERR

Возникает, если узел доступен только для чтения.

DOM_NOT_FOUND

Возникает, если oldnode не является дочерним узлом данного узла.

Примеры

Следующий пример удаляет элемент chapter (глава) из XML-документа.

Пример #1 Удаление дочернего узла

<?php

$doc 
= new DOMDocument;
$doc->load('book.xml');

$book $doc->documentElement;

// находим главу (chapter) и удалям из книги (book)
$chapter $book->getElementsByTagName('chapter')->item(0);
$oldchapter $book->removeChild($chapter);

echo 
$doc->saveXML();
?>

Результат выполнения данного примера:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
          "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<book id="listing">
 <title>My lists</title>

</book>

Пример #2 Сохраняем URI пространства имен родительского узла

<?php

$doc 
= new DOMDocument;
$doc->load('book.xml');

$book $doc->documentElement;

// находим главу (chapter) и удалям из книги (book)
$chapter $book->getElementsByTagName('chapter')->item(0);

// копируем URI пространства имен
$nsuri $book->namespaceURI;

// удаляем дочерний узел
$book->removeChild($chapter);

// вставляем URI пространства имен обратно в родительский узел
$book->namespaceURI $nsuri;
?>

Примечания

Замечание:

После вызова этого метода свойство DOMNode::$namespaceURI родительского узла сбрасывается в NULL. В примере выше показано, как это обойти.

Смотрите также

Коментарии

For those who don't understand >sbeam at onsetcorps dot net on 02-Feb-2005 12:07< 'hack', here's a little discussion:

First but *wrong* try would be:
<?php
foreach ($parent->childNodes as $child) {
   
$parent->removeChild($child);
?>
This doesn't work because DOM tree id modified on-the-fly and this confuses foreach loop.

The idea behind sbeam's trick is that after removing the first item in the first iteration, the second item in childNodes nodelist immediately becomes the first item. That's why we must _always_ remove the first child. Here's another implementation:

<?php
$count 
$parent->childNodes->length;
for (
$i 0$i $count$i++) {
   
$oldNode $parent->removeChild($parent->childNodes->item(0)); // !!! not item($i) !!!
}
?>
2005-02-13 05:35:09
http://php5.kiev.ua/manual/ru/domnode.removechild.html
You may also use the hasChild function:
<?php

while($node->hasChildNodes()) {
 
$node->removeChild($node->childNodes->item(0));
}

?>

When you remove a childNode, the next node becomes the first one!
2005-05-30 07:24:22
http://php5.kiev.ua/manual/ru/domnode.removechild.html
This might be obvious, but might help someone as well...

If you simply have a node that you need to remove (perhaps from an xpath) and don't know the parent node offhand (the examples seem to assume you have the parent in a variable), then you can do something easy like this...

$node->parentNode->removeChild($node);

parentNode is a scalar property of the Element.

Hope that helps.

--
Blaine Garrett
2005-08-23 13:10:47
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Back again on removing childs and iterators robustness. 

Things get a bit more complicated when you only want to remove 'some' nodes according to a certain condition. Then you can't just remove the first one repeatedly.

The trick is to copy the content of the node list into a more robust collection than DOMNodeList, I name array!

The following piece of code will, for instance, remove all empty child nodes:

<?php
// Copy childNodes array
$childNodes = array();
foreach(
$node->childNodes as $childNode) {
 
$childNodes[] = $childNode;
}

// Browse with the copy     
foreach ($childNodes as $childNode) {
  if (!
$childNode->hasChildNodes()); {
   
$childNode->parentNode->removeChild($childNode);
  }
}
?>
2005-09-07 05:20:23
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
At the time of writing, I suppose rightfully, removeChild() removes only the selected node, but when you remove an element, it's child elements are not removed. If you want to achieve that, replaceChild() is the solution.

The following should remove all descendants of the $node DOMNode, regardless of it's name:
<?php
$node
->replaceChild(new DOMElement($node->nodeName), $node);
?>
If you're replacing the root element, you must explicitly state that with $node->documentElement as the second argument.
2007-10-06 13:14:32
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
I used the following to delete an entire node using the child element:

<?php
$childElement
->parentNode->parentNode-> removeChild($childElement->parentNode);
?>

I could not have thought of it without the help of everyone who contributed to this thread.

Thanks!

(I had to introduce the extra space between parentNode->removeChild to get rid of the wordwrap() warning while posting this note)
2008-04-04 13:57:54
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Note that iterating through the childNodes array and removing those children will stop the iteration.

For example:
<?php
foreach($node->childNodes as $child)
{
  if(
iWantToDeleteThisNode($child))
     
$child->parentNode->removeChild($child);
}
?>

Will not work.  Note that in removing the node, the childNodes array gets rebuilt (it seems) and so only the first item will be removed.  In order to properly remove all the children you want to remove, you will need to do something like the following:

<?php
$nodesToDelete 
= array();
foreach(
$node->childNodes as $child)
{
  if(
iWantToDeleteThisNode($child))
   
$nodesToDelete[] = $child;
}
foreach(
$nodesToDelete as $node)
{
 
$node->parentNode->removeChild($node);
}
?>

I believe this is actually more efficient than the first snippet would be (if it worked) but obviously I cannot benchmark it.
2008-07-05 19:15:14
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
Or something like:

<?php

while ($node->childNodes->length)
     
$node->removeChild($node->firstChild);

?>
2008-07-19 16:00:15
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
These two functions might be helpful to anyone trying to delete a node and all of its children:

<?php
function deleteNode($node) {
   
deleteChildren($node);
   
$parent $node->parentNode;
   
$oldnode $parent->removeChild($node);
}

function 
deleteChildren($node) {
    while (isset(
$node->firstChild)) {
       
deleteChildren($node->firstChild);
       
$node->removeChild($node->firstChild);
    }
}
?>
2009-01-30 10:44:37
http://php5.kiev.ua/manual/ru/domnode.removechild.html
You can't remove DOMNodes from a DOMNodeList as you're iterating over them in a foreach loop. For example...

<?php
$domNodeList 
$domDocument->getElementsByTagname('p');
foreach ( 
$domNodeList as $domElement ) {
 
//  ...do stuff with $domElement...
 
$domElement->parentNode->removeChild($domElement);
}
?>

... will seemingly leave the internal iterator on the foreach out of wack and results will be quite strange. Though, making a queue of items to remove seems to work. For example...

<?php
$domNodeList 
$domDocument->getElementsByTagname('p');
$domElemsToRemove = array();
foreach ( 
$domNodeList as $domElement ) {
 
// ...do stuff with $domElement...
 
$domElemsToRemove[] = $domElement;
}
foreach( 
$domElemsToRemove as $domElement ){
 
$domElement->parentNode->removeChild($domElement);
}
?>
2009-04-15 04:50:04
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
Just a note, if you remove a node the whitespace it occupied will remain if you save the file.

To avoid this, use $document->preserveWhiteSpace = false;

For Example:

<?php
$document 
= new DomDocument();
$document->preserveWhiteSpace false;
?>
2009-11-05 13:46:33
http://php5.kiev.ua/manual/ru/domnode.removechild.html
If you try to remove children of a nested node (e.g. a <ul> list that contains another <ul>) and only remove the first level of child nodes, you'll get a messed-up node object.

Upon re-use of the messed-up node you'll get an error message that says: "Fatal error: Call to a member function blahblah() on a non-object".

To remove ALL child nodes, use this recursive function instead:
<?php
/**
 * Helper function that removes all child nodes of $node recursively
 * (i.e. including child nodes of the child nodes and so forth).
 */
function remove_children(&$node) {
  while (
$node->firstChild) {
    while (
$node->firstChild->firstChild) {
     
remove_children($node->firstChild);
    }
   
$node->removeChild($node->firstChild);
  }
}
?>
2010-02-11 17:37:18
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
This method will remove all child nodes but leave the attributes (and namespace declarations) intact.

<?php
function removeChildren( &$node )
{
 
$node->parentNode->replaceChild(
   
$n $node->cloneNodefalse ),
   
$node );

 
$node $n;
}
?>
2013-03-28 12:19:26
http://php5.kiev.ua/manual/ru/domnode.removechild.html
Автор:
You can use foreach to remove multiple elements from a DOMNodeList, only if you use a temporary array or via XPath query.
If not, the simplest way will be:

<?php

while ($element $nodeList->item(0)) {
   
$element->parentNode->removeChild($element);
}

?>
2019-02-01 04:29:56
http://php5.kiev.ua/manual/ru/domnode.removechild.html

    Поддержать сайт на родительском проекте КГБ