PHP 日本研討會 2024

DOMDocument::createElement

(PHP 5, PHP 7, PHP 8)

DOMDocument::createElement建立新的元素節點

描述

public DOMDocument::createElement(string $localName, string $value = ""): DOMElement|false

此函式會建立 DOMElement 類別的新執行個體。除非使用 (例如) DOMNode::appendChild() 插入,否則此節點不會顯示在文件中。

參數

localName

元素的標籤名稱。

value

元素的值。預設情況下,會建立一個空元素。該值也可以稍後使用 DOMElement::$nodeValue 設定。

該值會逐字使用,但 < 和 > 實體參照會逸脫。請注意,& 必須手動逸脫;否則它會被視為開始實體參照。此外," 不會被逸脫。

回傳值

如果發生錯誤,則傳回 DOMElement 類別的新執行個體或 false

錯誤/例外

DOM_INVALID_CHARACTER_ERR

如果 localName 包含無效字元,則會引發此錯誤。

範例

範例 #1 建立新元素並將其插入為根

<?php

$dom
= new DOMDocument('1.0', 'utf-8');

$element = $dom->createElement('test', 'This is the root element!');

// 我們將新元素插入為根 (文件的子節點)
$dom->appendChild($element);

echo
$dom->saveXML();
?>

以上範例會輸出

<?xml version="1.0" encoding="utf-8"?>
<test>This is the root element!</test>

範例 #2 傳遞包含未逸脫 & 的文字作為 value

<?php
$dom
= new DOMDocument('1.0', 'utf-8');
$element = $dom->createElement('foo', 'me & you');
$dom->appendChild($element);
echo
$dom->saveXML();
?>

以上範例將輸出類似以下內容

Warning: DOMDocument::createElement(): unterminated entity reference             you in /in/BjTCg on line 4
<?xml version="1.0" encoding="utf-8"?>
<foo/>

注意事項

注意:

value不會被逸脫。使用 DOMDocument::createTextNode() 建立具有逸脫支援的文字節點。

另請參閱

新增註解

使用者貢獻的註解 9 則註解

mikek dot nospam at nospam dot muonics dot com
17 年前
關於下面關於需要 htmlentities 以避免有關未終止實體參照的警告的註解,我認為值得一提的是,您不需要使用 createTextNode 和 DOMText::__construct。 如果您混合使用設定文字節點的兩種方法,並且 (或不) 將 htmlentities 一致地套用於所有要顯示的資料,您將會得到 &amp;s (或警告和格式錯誤的 xml)。

最好擴充 DOMElement 和 DOMDocument,以便它建立 DOMText 節點並附加它,而不是將它傳遞給 DOMElement 建構函式。 否則,祝您在程式碼的所有正確位置中使用 (或不使用) htmlentities 一切順利,特別是當程式碼變更時。

<?php

class XDOMElement extends DOMElement {
function
__construct($name, $value = null, $namespaceURI = null) {
parent::__construct($name, null, $namespaceURI);
}
}

class
XDOMDocument extends DOMDocument {
function
__construct($version = null, $encoding = null) {
parent::__construct($version, $encoding);
$this->registerNodeClass('DOMElement', 'XDOMElement');
}

function
createElement($name, $value = null, $namespaceURI = null) {
$element = new XDOMElement($name, $value, $namespaceURI);
$element = $this->importNode($element);
if (!empty(
$value)) {
$element->appendChild(new DOMText($value));
}
return
$element;
}
}

$doc1 = new XDOMDocument();
$doc1_e1 = $doc1->createElement('foo', 'bar & baz');
$doc1->appendChild($doc1_e1);
echo
$doc1->saveXML();

$doc2 = new XDOMDocument();
$doc2_e1 = $doc2->createElement('foo');
$doc2->appendChild($doc2_e1);
$doc2_e1->appendChild($doc2->createTextNode('bar & baz'));
echo
$doc2->saveXML();

?>

在 createElement 中指定的文字
<?xml version=""?>
<foo>bar &amp; baz</foo>

透過 createTextNode 加入的文字
<?xml version=""?>
<foo>bar &amp; baz</foo>
yasindagli at gmail dot com
15 年前
若要建立帶有屬性的元素,

<?php

function createElement($domObj, $tag_name, $value = NULL, $attributes = NULL)
{
$element = ($value != NULL ) ? $domObj->createElement($tag_name, $value) : $domObj->createElement($tag_name);

if(
$attributes != NULL )
{
foreach (
$attributes as $attr=>$val)
{
$element->setAttribute($attr, $val);
}
}

return
$element;
}

$dom = new DOMDocument('1.0', 'utf-8');

$elm = createElement($dom, 'foo', 'bar', array('attr_name'=>'attr_value'));

$dom->appendChild($elm);

echo
$dom->saveXML();

?>

輸出
<?xml version="1.0" encoding="utf-8"?>
<foo attr_name="attr_value">bar</foo>
sergsokolenko at gmail dot com
17 年前
為了避免「unterminated entity reference」的警告訊息,您可以使用 htmlentities() 來跳脫提供的數值
<?php
//...
$dom->createElement('name', htmlentities($text))
//...
?>
funkathustra
12 年前
雖然內建的 DOM 函式很棒,但由於它們被設計為支援通用的 XML,因此產生 HTML DOM 會變得特別冗長。我最後寫了這個函式來大幅加快速度。
而不是像這樣呼叫
<?php
$div
= $dom->createElement("div");
$div->setAttribute("class","MyClass");
$div->setAttribute("id","MyID");
$someOtherDiv->appendChild($div);
?>
你可以用以下方式完成相同的事情
<?php
$div
= newElement("div", $someOtherDiv, "class=MyClass;id=MyID");
?>
「key1=value;key2=value」的語法使用起來真的很快,但如果你的內容中包含這些字元,顯然就無法使用了。所以,你也可以傳遞一個陣列
<?php
$div
= newElement("div", $someOtherDiv, array("class","MyClass"));
?>
或是一個陣列的陣列,代表不同的屬性
<?php
$div
= newElement("form", $someOtherDiv, array(array("method","get"), array("action","/refer/?id=5");
?>

這是函式

<?php
function newElement($type, $insertInto = NULL, $params=NULL, $content="")
{
$tempEl = $this->dom->createElement($type, $content);
if(
gettype($params) == "string" && strlen($params) > 0)
{
$attributesCollection =split(";", $params);
foreach(
$attributesCollection as $attribute)
{
$keyvalue = split("=", $attribute);
$tempEl->setAttribute($keyvalue[0], $keyvalue[1]);
}
}
if(
gettype($params) == "array")
{
if(
gettype($params[0]) == "array")
{
foreach(
$params as $attribute)
{
$tempEl->setAttribute($attribute[0], $attribute[1]);
}
} else {
$tempEl->setAttribute($params[0], $params[1]);
}
}
?>
tschmieder at bitworks dot de
9 年前
請記住

如果您想對新節點執行多個動作,您可能需要在之前建立它的副本

意思是
## 建立到唯一記憶體區塊的位址!
$td = $dom->createElement('td');
## 變更此原始唯一模式中的一些內容
$td->setAttribute('class', 'saldo');

## 將獨特的模式複製成兩個獨立的實體
$td1 = clone $td;
$td2 = clone $td;

## 更改每個實體的屬性
$td1->nodeValue = '我是第一個新的節點';
$td2->nodeValue = '我是第二個新的節點';

## 找到父元素
$tr = $dom->getElementById('t001-tr001');
## 找到第一個和最後一個子節點 (這裡只是為了清楚起見)
$first = $tr->firstChild;
$last = $tr->lastChild;

## 產生新的節點
$newtd1 = $tr->insertBefore($td1, $first);
$newtd2 = $tr->appendChild($td2);

結論
每個動作都需要一個全新的原始節點!
lars dot c dot magnusson at gmail dot com
14 年前
您可能會認為 insertBefore 和 insertAfter 是 appendChild 的直接替代方案,但事實並非如此。

<?php
$dom
= new DOMDocument();
$dom->load($file);

$dom->appendChild($newNode); // 運作正常
$dom->insertBefore($newNode, $refNode); // 會失敗

$refNode->parentNode->insertBefore($newNode, $refNode); // 感謝 yasindagli (第一篇貼文)
?>
estill at gvtc dot com
17 年前
請注意,第二個參數 (value) 雖然方便,但並非標準。您應該像這樣建立元素:

<?php
$doc
= new DOMDocument('1.0', 'iso-8859-1');

$root = $doc->createElement('test');
$doc->appendChild($root);

$root_text = $doc->createTextNode('This is the root element!');
$root->appendChild($root_text);

print
$doc->saveXML();
?>

或者,您可以擴展 DOMDocument 類別並加入您自己的自訂便利方法,以避免干擾標準。

<?php
class CustomDOMDocument extends DOMDocument {
function
createElementWithText($name, $child_text) {
// 建立帶有子文字節點的元素

// @param string $name 元素標籤名稱
// @param string $child_text 子節點文字

// @return object 新元素

$element = $this->createElement($name);

$element_text = $this->createTextNode($child_text);
$element->appendChild($element_text);

return
$element;
}
}

$doc = new CustomDOMDocument('1.0', 'iso-8859-1');

$root = $doc->createElementWithText('test', 'This is the root element!');
$doc->appendChild($root);

print
$doc->saveXML();
?>

另外,請小心使用(或避免使用)'DOMElement->nodeValue' 屬性。它可能會傳回一些意想不到的值,而且變更其值會將元素的所有後代替換(移除)為單一文字節點。這也不是標準的;根據 DOM 規範,它應該傳回 NULL。
chris AT cmbuckley DOT co DOT uk
15 年前
請注意,NUL 字元 "\0" 不在 $name 的無效字元列表中,因此不會觸發錯誤,但標籤名稱將在空位元組處截斷

<?php

$dom
= new DOMDocument('1.0', 'utf-8');
$el = $dom->createElement('foo' . "\0" . 'bar', 'Hello World');
echo
$el->tagName; // 輸出 "foo"

?>
dignat at yahoo dot com
7 年前
使用 DomDocument 建立元素並逸出值中的 & 符號。

執行以下操作:

$element = new DOMDocument('1.0', 'UTF-8');

$test = $element->createElement('text');

$test ->appendChild($element->createElement('name'))
->appendChild($element->createtextNode('& I am ampersand');
To Top