DOMNode::insertBefore
(PHP 5)
DOMNode::insertBefore — Adds a new child before a reference node
Description
This function inserts a new node right before the reference node. If you plan to do further modifications on the appended child you must use the returned node.
Parameters
-
newnode
-
The new node.
-
refnode
-
The reference node. If not supplied,
newnode
is appended to the children.
Return Values
The inserted node.
Errors/Exceptions
-
DOM_NO_MODIFICATION_ALLOWED_ERR
-
Raised if this node is readonly or if the previous parent of the node being inserted is readonly.
-
DOM_HIERARCHY_REQUEST_ERR
-
Raised if this node is of a type that does not allow children of the type of the
newnode
node, or if the node to append is one of this node's ancestors or this node itself. -
DOM_WRONG_DOCUMENT_ERR
-
Raised if
newnode
was created from a different document than the one that created this node. -
DOM_NOT_FOUND
-
Raised if
refnode
is not a child of this node.
- PHP Руководство
- Функции по категориям
- Индекс функций
- Справочник функций
- Обработка XML
- Document Object Model
- Функция DOMNode::appendChild() - Добавляет новый дочерний узел в конец списка потомков
- Функция DOMNode::C14N() - Canonicalize nodes to a string
- Функция DOMNode::C14NFile() - Canonicalize nodes to a file
- Функция DOMNode::cloneNode() - Клонирует узел
- Функция DOMNode::getLineNo() - Возвращает номер строки узла
- Функция DOMNode::getNodePath() - Получение XPath пути к узлу
- Функция DOMNode::hasAttributes() - Проверяет, содержит ли данный узел атрибуты
- Функция DOMNode::hasChildNodes() - Проверяет, содержит ли данный узел потомков
- Функция DOMNode::insertBefore() - Добавляет новый дочерний узел перед опорным узлом
- Функция DOMNode::isDefaultNamespace() - Проверяет, совпадает ли URI пространства имен узла с пространством имен по умолчанию
- Функция DOMNode::isSameNode() - Проверяет, являются ли два узла одним и тем же узлом
- Функция DOMNode::isSupported() - Проверяет, поддерживается ли заданное свойство в определенной версии
- Функция DOMNode::lookupNamespaceURI() - Получает URI пространства имен узла по префиксу
- Функция DOMNode::lookupPrefix() - Возвращает префикс пространства имен узла из URI пространства имен
- Функция DOMNode::normalize() - Нормализует узел
- Функция DOMNode::removeChild() - Удаляет дочерний узел из списка потомков
- Функция DOMNode::replaceChild() - Заменяет дочерний узел
Коментарии
1st argument) a node to insert
2nd argument) a reference node - this is the node that the new node will be inserted before
The trick to using this method is that the OBJECT on which you actually CALL the insertBefore() method is actually the PARENT node of the reference node!
INCORRECT:
$DOMNode_refNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
CORRECT:
$DOMNode_refNode->parentNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
example to insert <newnode/> between <chid1/> and <child2/>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<root>
<parent>
<child nr="1"/>
<child nr="2"/>
</parent>
</root>
<?php
$xml_src = 'test.xml';
// XPath-Querys
$parent_path = "//parent";
$next_path = "//parent/child[@nr='2']";
// Create a new DOM document
$dom = new DomDocument();
$dom->load($xml_src);
// Find the parent node
$xpath = new DomXPath($dom);
// Find parent node
$parent = $xpath->query($parent_path);
// new node will be inserted before this node
$next = $xpath->query($next_path);
// Create the new element
$element = $dom->createElement('newnode');
// Insert the new element
$parent->item(0)->insertBefore($element, $next->item(0));
echo $dom->saveXML();
?>
The previous example is incorrect, and causes a DOM_NOT_FOUND error, as the child nodes are not direct descendants of the root node.
Therefore, the line:
$parent_path = "/root";
needs to change to:
$parent_path = "/root/parent";
or
$parent_path = "//parent";
for this example to work
Sorry, my previous posting worked only for the top node. Here the corrected version, which will work for any node:
XML
----
<?xml version="1.0"?>
<contacts>
<person>Adam</person>
<person>Eva</person>
<person>Thomas</person>
</contacts>
PHP
---
<?php
// load XML, create XPath object
$xml = new DomDocument();
$xml->preserveWhitespace = false;
$xml->load('contacts.xml');
$xpath = new DOMXPath($xml);
// get node eva, which we will append to
$eva = $xpath->query('/contacts/person[.="Eva"]')->item(0);
// create node john
$john = $xml->createElement('person', 'John');
// insert john after eva
// "in eva's parent node (=contacts) insert
// john before eva's next node"
// this also works if eva would be the last node
$eva->parentNode->insertBefore($john, $eva->nextSibling);
// show result
header('Content-Type: text/plain');
print $xml->saveXML();
?>
Result
------
<?xml version="1.0"?>
<contacts>
<person>Adam</person>
<person>Eva</person><person>John</person>
<person>Thomas</person>
</contacts>
Note that supplying the same node for $newnode and $refnode leads to an E_WARNING ("Couldn't add newnode as the previous sibling of refnode"). For example imagine one wanted to make $newnode the first child of its parent by doing:
<?php
$firstSibling = $newnode->parentNode->firstChild;
// Bad:
$newnode->parentNode->insertBefore( $newnode, $firstSibling );
?>
This would generate a warning if it already was the first child of its parent, since $newnode and $firstSibling are identical. Easy to work around though:
<?php
$firstSibling = $newnode->parentNode->firstChild;
// Better:
if( $newnode !== $firstSibling ) {
$newnode->parentNode->insertBefore( $newnode, $firstSibling );
}
?>