2024 日本 PHP 研討會

DOMDocument::registerNodeClass

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

DOMDocument::registerNodeClass註冊用於建立基礎節點類型的擴充類別

說明

public DOMDocument::registerNodeClass(字串 $baseClass, ?字串 $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
class MyDOMDocument extends DOMDocument {
}

class
MyOtherDOMDocument extends 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
class MyDOMElement extends 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 則註解

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

<?php

類別 DOMHTMLElement 繼承 DOMElement
{
函式
__construct() { parent::__construct();}

公開函式
innerHTML()
{
$doc = new DOMDocument();
foreach (
$this->childNodes as $child){
$doc->appendChild($doc->importNode($child, true));
}
$content = $doc->saveHTML();
return
$content;
}

公開函式
outerHTML()
{
$doc = new DOMDocument();
$doc->appendChild($doc->importNode($this, true));
$content = $doc->saveHTML();
return
$content;
}
}

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

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

foreach(
$regions as $region){
$content .= $region->outerHTML();
}

return
$content;

}else{
throw new
Exception('無法解析 HTML。請確認語法正確。');
}
?>
1
arnold at adaniels dot nl
15 年前
請注意,save 和 saveXML 不受 __toString() 影響。
To Top