CakeFest 2024: The Official CakePHP Conference

DOMNode::insertBefore

(PHP 5, PHP 7, PHP 8)

DOMNode::insertBefore 参照しているノードの前に新しい子を追加する

説明

public DOMNode::insertBefore(DOMNode $node, ?DOMNode $child = null): DOMNode|false

この関数は、参照しているノードの直前に新しいノードを挿入します。 追加するノードに対して変更を加えたい場合は、この関数から返される ノードを使用します。

既存のノードを使う場合、そのノードは移動します。

パラメータ

node

新しいノード。

child

参照ノード。指定されなかった場合は、node が子要素として追加されます。

戻り値

挿入されたノードを返します。 エラーの場合は false を返します。

エラー / 例外

DOM_NO_MODIFICATION_ALLOWED_ERR

このノードが読み込み専用であったり、挿入されるノードの以前の親が 読み込み専用であった場合に発生します。

DOM_HIERARCHY_REQUEST_ERR

node で指定した型の子ノードを 保持することが許可されていない場合、あるいは追加しようとしている ノードが自分自身やその祖先であった場合に発生します。

DOM_WRONG_DOCUMENT_ERR

node が、このノードとは別の ドキュメントで作成されたものである場合に発生します。

DOM_NOT_FOUND

child がこのノードの子ではない場合に 発生します。

参考

add a note

User Contributed Notes 5 notes

up
16
Jerry Ellis
18 years ago
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);
up
5
jarry1250 at gmail dot com
8 years ago
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 );
}
?>
up
7
jg at handcode dot de
18 years ago
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();

?>
up
-3
DrTebi at Yahoo
16 years ago
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>
up
-5
justin at redwiredesign dot com
17 years ago
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
To Top