DOMNode::cloneNode

(PHP 5, PHP 7, PHP 8)

DOMNode::cloneNode克隆节点

描述

public DOMNode::cloneNode(bool $deep = false): DOMNode|false

创建节点的副本。

参数

deep

指示是否复制所有后代节点。此参数默认为 false

返回值

克隆的节点。

添加注释

用户贡献的注释 6 个注释

8
frame at dynamiccreated dot de
11 年前
请记住,DOMNode 始终需要对父节点或 DOMDocument 的引用。

例如,如果您尝试克隆一个节点 - 复制所有子节点 - 并覆盖或删除保存克隆节点的变量 - 所有子节点将失去任何引用并变得无效。

如果幸运的话,这会导致一个像“无法... 节点不再存在”这样的好消息。在大多数情况下,PHP 只会给您提供“无法获取 DOM[...]”的简陋信息,这使得很难找出发生了什么,具体取决于当前的操作。
5
[montana] at [percepticon] dot [com]
15 年前
<?php

//@oliver 感谢示例源代码...

/*
cloneNode(false) 不会省略
克隆节点的属性,
要实现这一点,需要进行迭代。
这可能效率低于
仅仅从所需的节点名称
创建一个新节点
但在某些情况下可能很有用。

用例:

省略 XML 文档中
保护部分的子节点和属性
而不改变预期的通用结构;
*/
// 要使用的 xml

$file="<?xml version='1.0'?>
<book type='paperback'>
<title name='MAP'>Red Nails</title>
<price>$12.99</price>
<author>
<name first='Robert' middle='E' last='Howard'/>
<birthdate disco='false' nirvana='definitely'>
9/21/1977
<month title='september' />
</birthdate>
</author>
<author>
<name first='Arthur' middle='Mc' last='Kayn'/>
</author>
</book>"
;

$doc = new domDocument;

$doc->loadXML($file);

$xpath = new domXPath($doc);

$query = "//author/birthdate";
$xpathQuery = $xpath->query($query);

// 在生产代码中将是一个循环...
$child = $xpathQuery->item(0);

$parent = $child->parentNode;

$doppel = $child->cloneNode(false);

$limit = $doppel->attributes->length;

for (
$a=0;$a<$limit;$a++) {
$doppel->removeAttributeNode($doppel->attributes->item(0));
}
// 现在用空节点交换
$parent->replaceChild( $doppel, $child);

print
$doc->saveXML();

?>
2
cmd at 1xinternet dot de
7 年前
如果您需要克隆包含所有子 DOMNode 元素的节点

private function cloneNode($node){

$nd = new DOMNode();

for ($i = 0; $i < $node->childNodes->length; $i++) {
$child = $node->childNodes->item($i);
if ($child->nodeType === XML_TEXT_NODE) {
$nd->appendChild($node->cloneNode(true));
}
else{
$nd->appendChild($this->cloneNode($child));
}
}

return $nd;
}
2
cemkalyoncu at gmail dot com
15 年前
如果您需要某个函数来克隆节点而不触及命名空间,您可以使用以下代码。

<?php
private function cloneNode($node,$doc){
$nd=$doc->createElement($node->nodeName);

foreach(
$node->attributes as $value)
$nd->setAttribute($value->nodeName,$value->value);

if(!
$node->childNodes)
return
$nd;

foreach(
$node->childNodes as $child) {
if(
$child->nodeName=="#text")
$nd->appendChild($doc->createTextNode($child->nodeValue));
else
$nd->appendChild(cloneNode($child,$doc));
}

return
$nd;
}
?>
2
h-fate at gmx dot net
9 年前
如果您有一个保存 DOMNode 的对象,克隆该对象不会同时克隆 DOMNode。如果您只是复制对象或多次添加其 DOMNode,实际上您只会移动 DOMNode 在树中的位置,而不是复制它。这似乎显而易见,但我花了半天时间才弄明白。

该对象需要使用 __clone 手动克隆节点

<?php
class containsNode {
public
$node; // 从某处设置

public function __clone() {
$this->node = $this->node->cloneNode(TRUE);
}
}
?>
-5
oliver dot christen at camptocamp dot com
19 年前
节点克隆的简单示例

<?xml version="1.0"?>

<book type="paperback">
<title name='MAP'>Red Nails</title>
<price>$12.99</price>
<author>
<name first="Robert" middle="E" last="Howard"/>
<birthdate>9/21/1977</birthdate>
</author>
<author>
<name first="Arthur" middle="Mc" last="Kayn"/>
</author>
</book>

<?php

// 要使用的 xml 文件名
$file = 'book.xml';

$doc = new domDocument;

if (
file_exists($file)) {
$doc->load($file);
} else {
exit(
'错误!');
}

$xpath = new domXPath($doc);

$query = "//author/*";
$xpathQuery = $xpath->query($query);

$size = $xpathQuery->length;
for (
$i=0; $i<$size; $i++){
$node = $xpathQuery->item($i);
if (
$node->nodeName == 'birthdate' && $node->hasChildNodes() && $node->firstChild->textContent != ''){
$clonenode = $node->cloneNode(true);
$refnode = $node;
}
}
for (
$i=0; $i<$size; $i++){
$node = $xpathQuery->item($i);
if (!
$node->isSameNode($refnode)){
$newnode = $node->appendChild($clonenode);
}
}

print
$doc->saveXML();

?>
To Top