第一個參數) 要插入的節點
第二個參數) 參考節點 - 這是新節點將在其之前插入的節點
使用此方法的訣竅是,實際呼叫 insertBefore() 方法的物件實際上是參考節點的父節點!
錯誤
$DOMNode_refNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
正確
$DOMNode_refNode->parentNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
(PHP 5, PHP 7, PHP 8)
DOMNode::insertBefore — 在參考節點之前新增子節點
此函式會在參考節點之前插入一個新的節點。如果您計畫對附加的子節點進行進一步的修改,則必須使用返回的節點。
使用現有節點時,它將被移動。
node
新的節點。
child
參考節點。如果未提供,node
將附加到子節點列表的末尾。
插入的節點,或錯誤時返回 false
。
DOM_NO_MODIFICATION_ALLOWED_ERR
如果此節點是唯讀的,或者要插入的節點的前一個父節點是唯讀的,則會引發此錯誤。
DOM_HIERARCHY_REQUEST_ERR
如果此節點的類型不允許 node
節點類型的子節點,或者要附加的節點是此節點的祖先之一或此節點本身,則會引發此錯誤。
DOM_WRONG_DOCUMENT_ERR
如果 node
是從與創建此節點不同的文件創建的,則會引發此錯誤。
DOM_NOT_FOUND_ERR
如果 child
不是此節點的子節點,則會引發此錯誤。
第一個參數) 要插入的節點
第二個參數) 參考節點 - 這是新節點將在其之前插入的節點
使用此方法的訣竅是,實際呼叫 insertBefore() 方法的物件實際上是參考節點的父節點!
錯誤
$DOMNode_refNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
正確
$DOMNode_refNode->parentNode->insertBefore($DOMNode_newNode, $DOMNode_refNode);
請注意,為 $newnode 和 $refnode 提供相同的節點會導致 E_WARNING(「無法將 newnode 新增為 refnode 的前一個兄弟節點」)。例如,想像一下,如果想通過以下操作使 $newnode 成為其父節點的第一個子節點
<?php
$firstSibling = $newnode->parentNode->firstChild;
// 錯誤:
$newnode->parentNode->insertBefore( $newnode, $firstSibling );
?>
如果它已經是其父節點的第一個子節點,則會產生警告,因為 $newnode 和 $firstSibling 是相同的。不過很容易解決
<?php
$firstSibling = $newnode->parentNode->firstChild;
// 更好的做法:
if( $newnode !== $firstSibling ) {
$newnode->parentNode->insertBefore( $newnode, $firstSibling );
}
?>
範例:在 <chid1/> 和 <child2/> 之間插入 <newnode/>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<root>
<parent>
<child nr="1"/>
<child nr="2"/>
</parent>
</root>
<?php
$xml_src = 'test.xml';
// XPath 查詢
$parent_path = "//parent";
$next_path = "//parent/child[@nr='2']";
// 建立新的 DOM 文件
$dom = new DomDocument();
$dom->load($xml_src);
// 尋找父節點
$xpath = new DomXPath($dom);
// 尋找父節點
$parent = $xpath->query($parent_path);
// 新節點將會插入在此節點之前
$next = $xpath->query($next_path);
// 建立新元素
$element = $dom->createElement('newnode');
// 插入新元素
$parent->item(0)->insertBefore($element, $next->item(0));
echo $dom->saveXML();
?>
抱歉,我之前的貼文只適用於頂層節點。這裡是修正後的版本,適用於任何節點
XML
----
<?xml version="1.0"?>
<contacts>
<person>Adam</person>
<person>Eva</person>
<person>Thomas</person>
</contacts>
PHP
---
<?php
// 載入 XML,建立 XPath 物件
$xml = new DomDocument();
$xml->preserveWhitespace = false;
$xml->load('contacts.xml');
$xpath = new DOMXPath($xml);
// 取得 eva 節點,我們將在其後附加新節點
$eva = $xpath->query('/contacts/person[.="Eva"]')->item(0);
// 建立 john 節點
$john = $xml->createElement('person', 'John');
// 將 john 插入到 eva 之後
// 「在 eva 的父節點 (=contacts) 中插入
// john 在 eva 的下一個節點之前」
// 即使 eva 是最後一個節點,這也能正常運作
$eva->parentNode->insertBefore($john, $eva->nextSibling);
// 顯示結果
header('Content-Type: text/plain');
print $xml->saveXML();
?>
結果
------
<?xml version="1.0"?>
<contacts>
<person>Adam</person>
<person>Eva</person><person>John</person>
<person>Thomas</person>
</contacts>
先前的範例不正確,並且會導致 DOM_NOT_FOUND 錯誤,因為子節點不是根節點的直接子節點。
因此,這一行
$parent_path = "/root";
需要改成
$parent_path = "/root/parent";
或
$parent_path = "//parent";
才能讓這個範例正常運作