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 个注释

14
mikek dot nospam at nospam dot muonics dot com
17 年前
关于下面关于需要 htmlentities 以避免关于未终止实体引用的警告的注释,我认为有必要提到,在使用 createTextNode 和 DOMText::__construct 时,您不需要使用 htmlentities。如果您混合使用两种设置文本节点的方法,并且始终(或不)一致地对所有要显示的数据应用 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>
5
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>
8
sergsokolenko at gmail dot com
17 年前
为了避免警告消息“未结束的实体引用”,你可以使用 htmlentities() 来转义提供的 value
<?php
//...
$dom->createElement('name', htmlentities($text))
//...
?>
6
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]);
}
}
?>
2
tschmieder at bitworks dot de
9 年前
记住

如果你想对新节点执行多个操作,你可能需要在操作之前创建它的副本

意味着
## 创建一个指向唯一内存块的地址!
$td = $dom->createElement('td');
## 在这个原始的唯一模式中更改一些东西
$td->setAttribute('class', 'saldo');

## 将唯一模式克隆到两个自己的模式中
$td1 = clone $td;
$td2 = clone $td;

## 在每个模式中更改属性
$td1->nodeValue = 'Ich bin die erste neue Node';
$td2->nodeValue = 'Ich bin die zweite neue Node';

## 找到父元素
$tr = $dom->getElementById('t001-tr001');
## 找到第一个和最后一个子节点(这里只是为了清晰起见)
$first = $tr->firstChild;
$last = $tr->lastChild;

## 生成新的节点
$newtd1 = $tr->insertBefore($td1, $first);
$newtd2 = $tr->appendChild($td2);

结论
每个操作都需要一个原始的新节点!
3
lars dot c dot magnusson at gmail dot com
13 年前
您可能认为 insertBefore 和 insertAfter 是 appendChild 的直接替代方案,但事实并非如此。

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

$dom->appendChild($newNode); // 正常工作
$dom->insertBefore($newNode, $refNode); // 将失败

$refNode->parentNode->insertBefore($newNode, $refNode); // 感谢 yasindagli (第一条帖子)
?>
4
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。
2
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"

?>
-1
dignat at yahoo dot com
6 年前
要使用 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