PHP Conference Japan 2024

DOMDocument::registerNodeClass

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

DOMDocument::registerNodeClass注册用于创建基本节点类型的扩展类

描述

public DOMDocument::registerNodeClass(string $baseClass, ?string $extendedClass): true

此方法允许您注册您自己的扩展 DOM 类,以便之后由 PHP DOM 扩展使用。

此方法不是 DOM 标准的一部分。

注意

不会调用已注册节点类的对象的构造函数。

参数

baseClass

您想要扩展的 DOM 类。您可以在 章节介绍 中找到这些类的列表。

extendedClass

您的扩展类名。如果提供 null,则将删除以前注册的扩展 baseClass 的任何类。

返回值

始终返回 true

变更日志

版本 描述
8.4.0 DOMDocument::registerNodeClass() 现在具有 true 的暂定返回值。

示例

示例 #1 向 DOMElement 添加新方法以简化我们的代码

<?php

class myElement extends DOMElement {
function
appendElement($name) {
return
$this->appendChild(new myElement($name));
}
}

class
myDocument extends DOMDocument {
function
setRoot($name) {
return
$this->appendChild(new myElement($name));
}
}

$doc = new myDocument();
$doc->registerNodeClass('DOMElement', 'myElement');

// 从现在开始,向另一个元素添加元素只需要一个方法调用!
$root = $doc->setRoot('root');
$child = $root->appendElement('child');
$child->setAttribute('foo', 'bar');

echo
$doc->saveXML();

?>

以上示例将输出

<?xml version="1.0"?>
<root><child foo="bar"/></root>

示例 #2 以自定义类检索元素

<?php
class myElement extends DOMElement {
public function
__toString() {
return
$this->nodeValue;
}
}

$doc = new DOMDocument;
$doc->loadXML("<root><element><child>text in child</child></element></root>");
$doc->registerNodeClass("DOMElement", "myElement");

$element = $doc->getElementsByTagName("child")->item(0);
var_dump(get_class($element));

// 并利用 __toString 方法..
echo $element;
?>

以上示例将输出

string(9) "myElement"
text in child

示例 #3 检索所有者文档

在实例化自定义 DOMDocument 时,ownerDocument 属性将引用实例化的类。但是,如果删除对该类的所有引用,它将被销毁,并且会创建新的 DOMDocument。出于这个原因,您可能需要使用 DOMDocument::registerNodeClass()DOMDocument

<?php
MyDOMDocument 扩展 DOMDocument {
}

MyOtherDOMDocument 扩展 DOMDocument {
}

// 使用一些 XML 创建 MyDOMDocument
$doc = new MyDOMDocument;
$doc->loadXML("<root><element><child>text in child</child></element></root>");

$child = $doc->getElementsByTagName("child")->item(0);

// 节点的当前所有者是 MyDOMDocument
var_dump(get_class($child->ownerDocument));
// MyDOMDocument 被销毁
unset($doc);
// 并创建新的 DOMDocument 实例
var_dump(get_class($child->ownerDocument));

// 从 MyDOMDocument 导入节点
$newdoc = new MyOtherDOMDocument;
$child = $newdoc->importNode($child);

// 注册自定义 DOMDocument
$newdoc->registerNodeClass("DOMDocument", "MyOtherDOMDocument");

var_dump(get_class($child->ownerDocument));
unset(
$doc);
// 创建新的 MyOtherDOMDocument
var_dump(get_class($child->ownerDocument));
?>

以上示例将输出

string(13) "MyDOMDocument"
string(11) "DOMDocument"
string(18) "MyOtherDOMDocument"
string(18) "MyOtherDOMDocument"

示例 #4 自定义对象是短暂的

注意

已注册节点类的对象是短暂的,即当它们不再被 PHP 代码引用时会被销毁,并在再次被检索时重新创建。这意味着自定义属性值在重新创建后将丢失。

<?php
MyDOMElement 扩展 DOMElement
{
public
$myProp = 'default value';
}

$doc = new DOMDocument();
$doc->registerNodeClass('DOMElement', 'MyDOMElement');

$node = $doc->createElement('a');
$node->myProp = 'modified value';
$doc->appendChild($node);

echo
$doc->childNodes[0]->myProp, PHP_EOL;
unset(
$node);
echo
$doc->childNodes[0]->myProp, PHP_EOL;
?>

以上示例将输出

modified value
default value

添加注释

用户贡献的注释 2 条注释

crh3675 at gmail dot com
15 年前
创建 innerHTML 和 outerHTML

<?php

DOMHTMLElement 扩展 DOMElement
{
函数
__construct() { parent::__construct();}

public 函数
innerHTML()
{
$doc = new DOMDocument();
遍历 (
$this->childNodes 作为 $child){
$doc->appendChild($doc->importNode($child, true));
}
$content = $doc->saveHTML();
返回
$content;
}

public 函数
outerHTML()
{
$doc = new DOMDocument();
$doc->appendChild($doc->importNode($this, true));
$content = $doc->saveHTML();
返回
$content;
}
}

$dom = DOMDocument::loadHTMLFile($file);
$dom->registerNodeClass('DOMElement','DOMHTMLElement');

如果(
$dom)
{
$xpath = new DOMXpath($dom);
$regions = $xpath->query("//*[contains(@class, 'editable')]");
$content = '';

遍历(
$regions 作为 $region){
$content .= $region->outerHTML();
}

返回
$content;

}其他{
抛出 new
Exception('无法解析 HTML。请验证语法是否正确。');
}
?>
arnold at adaniels dot nl
15 年前
注意 save 和 saveXML 不受 __toString() 的影响。
To Top