CakeFest 2024: The Official CakePHP Conference

DOMDocument::registerNodeClass

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

DOMDocument::registerNodeClass基底ノード型を作成する際に使用する拡張クラスを登録する

説明

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

このメソッドにより、独自に拡張した DOM クラスを登録することができます。 これを、後で PHP DOM 拡張モジュールで使用します。

このメソッドは、DOM の標準にはないものです。

警告

登録済みのクラスの、インスタンスのコンストラクタはコールされません。

パラメータ

baseClass

拡張したい DOM クラス。クラス名の一覧は、 この章の導入部にあります。

extendedClass

拡張したクラスの名前。null を渡した場合は、 それまでに baseClass を拡張して作成したすべてのクラスが削除されます。

戻り値

成功した場合に true を、失敗した場合に false を返します。

例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 からノードを import します
$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

add a note

User Contributed Notes 2 notes

up
4
crh3675 at gmail dot com
14 years ago
Creating innerHTML and outerHTML

<?php

class DOMHTMLElement extends DOMElement
{
function
__construct() { parent::__construct();}

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

public function
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('Cannot parse HTML. Please verify the syntax is correct.');
}
?>
up
1
arnold at adaniels dot nl
14 years ago
Note than save and saveXML are not affected by __toString().
To Top