Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】DOMEntityReference::nodeValueプロパティの使い方

nodeValueプロパティの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

nodeValueプロパティは、ノードの値を保持するプロパティです。このプロパティはDOMNodeクラスから継承されており、その挙動はノードの種類によって異なります。DOMEntityReferenceクラスのインスタンス、すなわちXMLやHTMLドキュメント内のエンティティ参照ノード(例: &example;)の場合、このnodeValueプロパティは常にnullを返します。これは、エンティティ参照ノード自体が具体的な値を持つのではなく、あらかじめ定義されたエンティティへの参照を示す役割を担っているためです。エンティティが実際に表す内容、例えば特定のテキストや他のノード群を取得したい場合は、このエンティティ参照ノードの子ノードにアクセスする必要があります。childNodesプロパティなどを通じて子ノード群を取得し、その中のテキストノードなどのnodeValueを調べることで、展開されたコンテンツを得ることができます。したがって、DOMEntityReferenceオブジェクトに対して直接nodeValueを参照しても値は得られず、また値を設定しようとしてもその操作は無視されます。

構文(syntax)

1<?php
2$xml = <<<XML
3<?xml version="1.0" encoding="UTF-8"?>
4<!DOCTYPE doc [
5<!ENTITY company "My Company">
6]>
7<doc>
8  <author>&company;</author>
9</doc>
10XML;
11
12$dom = new DOMDocument();
13$dom->loadXML($xml);
14
15// <author> タグの子ノードである DOMEntityReference オブジェクトを取得
16$entityRefNode = $dom->getElementsByTagName('author')->item(0)->childNodes->item(0);
17
18// DOMEntityReference::$nodeValue プロパティにアクセスします。
19// このプロパティの値は常に null です。
20$value = $entityRefNode->nodeValue;
21
22var_dump($value); // NULL
23?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

string|null

DOMエンティティ参照ノードのテキスト値、またはノードがテキスト値を持たない場合はnullを返します。

サンプルコード

PHP DOMEntityReference::nodeValue を確認する

1<?php
2
3/**
4 * DOMEntityReference::nodeValue プロパティの動作を示すサンプル関数。
5 *
6 * DOMEntityReference ノードの nodeValue は常に NULL です。
7 * これは、エンティティ参照自体が値を保持せず、参照先のエンティティ定義が
8 * 実際のコンテンツであるためです。
9 *
10 * XML内のエンティティ参照を DOMEntityReference オブジェクトとして取得するためには、
11 * DOMDocument::loadXML() に LIBXML_NOENT オプションを指定し、
12 * エンティティ参照を展開しないようにする必要があります。
13 */
14function demonstrateDomEntityReferenceNodeValue(): void
15{
16    // 1. DOMDocument オブジェクトを作成
17    $dom = new DOMDocument();
18    // DOMツリーの整形出力と空白ノードの無視設定(オプション)
19    $dom->preserveWhiteSpace = false;
20    $dom->formatOutput = true;
21
22    // 2. エンティティ参照とそれを定義するDTDを含むXML文字列
23    // <!DOCTYPE> で内部DTDを定義し、<!ENTITY> で 'myentity' を宣言します。
24    // <root> 要素内で '&myentity;' を参照しています。
25    $xmlString = <<<XML
26<!DOCTYPE root [
27  <!ENTITY myentity "エンティティの値">
28]>
29<root>これは &myentity; テストです。</root>
30XML;
31
32    echo "--- 元のXML ---\n";
33    echo $xmlString . "\n\n";
34
35    // 3. XMLをロード。LIBXML_NOENT オプションでエンティティ参照を展開しないように指定
36    // これにより、DOMツリー内に DOMEntityReference オブジェクトが保持されます。
37    if (!$dom->loadXML($xmlString, LIBXML_NOENT)) {
38        echo "エラー: XMLのロードに失敗しました。\n";
39        return;
40    }
41
42    echo "--- パース後のDOMツリー (DOMEntityReference を含む) ---\n";
43    echo $dom->saveXML() . "\n";
44
45    // 4. DOMEntityReference ノードを見つける
46    // <root> 要素の子ノードをループし、DOMEntityReference 型のノードを探します。
47    $entityReferenceNode = null;
48    $rootElement = $dom->getElementsByTagName('root')->item(0);
49    if ($rootElement) {
50        foreach ($rootElement->childNodes as $node) {
51            if ($node instanceof DOMEntityReference) {
52                $entityReferenceNode = $node;
53                break;
54            }
55        }
56    }
57
58    echo "--- DOMEntityReference ノードの確認 ---\n";
59    if ($entityReferenceNode instanceof DOMEntityReference) {
60        echo "  DOMEntityReference ノードが見つかりました。\n";
61        echo "  ノード名: " . $entityReferenceNode->nodeName . "\n"; // 例: myentity
62
63        // 5. DOMEntityReference::nodeValue にアクセスし、値を出力
64        $nodeValue = $entityReferenceNode->nodeValue;
65
66        echo "  nodeValue の値: " . var_export($nodeValue, true) . "\n";
67
68        // 6. nodeValue が NULL になる理由を補足
69        echo "  ※ DOMEntityReference の nodeValue は常に NULL です。\n";
70        echo "  これは、エンティティ参照自体が値を直接保持しないためです。\n";
71    } else {
72        echo "  DOMEntityReference ノードが見つかりませんでした。\n";
73        echo "  LIBXML_NOENT オプションが正しく適用されているか確認してください。\n";
74    }
75}
76
77// サンプル関数を実行
78demonstrateDomEntityReferenceNodeValue();

DOMEntityReference::nodeValueプロパティは、PHPのDOM拡張機能におけるエンティティ参照ノードの値を表します。このプロパティは引数を取らず、戻り値は文字列またはnullとなります。

サンプルコードは、XML内のエンティティ参照をDOMEntityReferenceオブジェクトとして扱い、そのnodeValuenullとなる挙動を示しています。通常、XMLをパースする際、エンティティ参照は参照先のコンテンツに展開されますが、DOMDocument::loadXML()関数にLIBXML_NOENTオプションを指定することで、エンティティ参照が展開されずにDOMEntityReferenceオブジェクトとしてDOMツリー内に残ります。

DOMEntityReferenceオブジェクトのnodeValueプロパティは、常にnullを返します。これは、エンティティ参照ノード自体が直接的な値を保持するのではなく、参照先のエンティティ定義が実際のコンテンツであるためです。したがって、エンティティ参照の具体的な内容を取得したい場合は、DOMEntityReferenceノードそのものではなく、それが参照するエンティティの定義を参照する必要があります。この特性を理解することで、XMLドキュメントの構造とDOM操作をより正確に行うことができます。

このサンプルコードの最も重要な注意点は、DOMEntityReference::nodeValueが常にNULLを返すことです。エンティティ参照ノード自体は値を直接持たず、参照先のコンテンツを示すため、このプロパティから具体的な値は取得できません。DOMEntityReferenceオブジェクトをDOMツリーに含めてこの挙動を確認するには、DOMDocument::loadXML()メソッドにLIBXML_NOENTオプションを必ず指定してください。このオプションがない場合、XMLロード時にエンティティ参照が自動的に展開されてしまい、DOMEntityReference型のノードはDOMツリーに現れません。これらの仕様を理解し、安全かつ正確にXMLを処理することが大切です。

PHP: nodeValue vs textContent 比較

1<?php
2
3declare(strict_types=1);
4
5/**
6 * DOMNodeの nodeValue と textContent プロパティの違いを比較します。
7 *
8 * `nodeValue` は、主にテキストノードやコメントノード自身の値を取得するために使用します。
9 * 要素ノードに対して使用すると `null` を返します。
10 *
11 * `textContent` は、要素ノードとそのすべての子孫ノードに含まれるテキストを
12 * 連結した文字列を取得します。HTMLタグは除去されます。
13 */
14function compareNodeValueAndTextContent(): void
15{
16    // 比較用のHTMLコンテンツ
17    $html = <<<HTML
18    <div id="container">
19        Hello <strong>World</strong>! <!-- This is a comment -->
20    </div>
21    HTML;
22
23    // DOMDocumentオブジェクトを作成し、HTMLを読み込む
24    $dom = new DOMDocument();
25    $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
26
27    // id="container" の div 要素を取得
28    $element = $dom->getElementById('container');
29
30    if ($element === null) {
31        echo 'Element not found.' . PHP_EOL;
32        return;
33    }
34
35    // --- 要素ノード (div) に対する比較 ---
36
37    // nodeValue: 要素ノード自体はテキスト値を持たないため、null を返します。
38    echo 'Element nodeValue: ';
39    var_dump($element->nodeValue); // 出力: NULL
40
41    // textContent: 子要素のタグを除いた、すべてのテキストコンテンツを連結して返します。
42    // 前後の空白や改行も含まれる点に注意してください。
43    echo 'Element textContent: ';
44    var_dump(trim($element->textContent)); // 出力: string(12) "Hello World!"
45
46
47    // --- テキストノード ("Hello ") に対する比較 ---
48    $textNode = $element->firstChild; // div要素の最初の子ノード("Hello "というテキストノード)
49
50    if ($textNode instanceof DOMText) {
51        // nodeValue: テキストノード自身の値を返します。
52        echo 'Text nodeValue: ';
53        var_dump($textNode->nodeValue); // 出力: string(6) "Hello "
54
55        // textContent: テキストノードの場合、nodeValue と同じ値を返します。
56        echo 'Text textContent: ';
57        var_dump($textNode->textContent); // 出力: string(6) "Hello "
58    }
59}
60
61// 関数を実行
62compareNodeValueAndTextContent();

nodeValueは、DOMの特定のノードが持つ自身の値を直接取得するためのプロパティです。引数はなく、ノードの種類に応じて文字列またはnullを返します。

このプロパティの挙動は、よく似たtextContentプロパティと比較することでより明確に理解できます。サンプルコードでは、HTMLのdiv要素、すなわち「要素ノード」に対してnodeValueを使用するとnullが返されます。これは、要素ノード自体は直接的なテキスト値を持たないためです。一方、textContentは、そのdiv要素の内部にあるすべての子孫ノードからテキスト部分だけを連結した「Hello World!」という文字列を返します。

次に、div要素の子である「Hello 」という「テキストノード」で両者を比較すると、nodeValuetextContentはどちらも同じ「Hello 」という文字列を返します。

このように、nodeValueはテキストノードやコメントノードなど、ノード自身の値を取得する場合に限定して使用します。対してtextContentは、ある要素とそのすべての子孫に含まれるテキストをまとめて取得したい場合に利用するという明確な違いがあります。

nodeValuetextContentは取得できる値が異なるため、目的に応じた使い分けが必要です。nodeValueはテキストやコメントといった、ノード自身の値を取得するためのプロパティです。<div>のような要素ノードはテキストとしての値を持たないため、nodeValueで値を取得しようとするとnullが返るので注意しましょう。一方、textContentは指定した要素とその子孫に含まれるテキストを、HTMLタグなどを除いて全て連結して返します。要素内の表示テキストをまとめて取得したい場合に便利です。textContentには意図しない空白が含まれることがあるため、trim()関数などで整形するとより安全に扱えます。

PHP DOMEntityReference nodeValue の動作

1<?php
2
3/**
4 * DOMEntityReferenceクラスのnodeValueプロパティの使用例を示します。
5 *
6 * PHPのDOM拡張機能では、通常、XMLパーサーがエンティティ参照を展開してしまうため、
7 * DOMツリー内でDOMEntityReferenceノードに直接遭遇することは稀です。
8 * しかし、もしDOMEntityReferenceのインスタンスが存在する場合、
9 * そのnodeValueプロパティは常にNULLを返します。
10 * これはエンティティ参照自体の値を表すものではなく、エンティティの内容を取得する用途には使えません。
11 *
12 * @return void
13 */
14function demonstrateDomEntityReferenceNodeValue(): void
15{
16    // DOMEntityReferenceのインスタンスを直接作成します。
17    // 'myEntity' は参照されるエンティティの名前です。
18    // このインスタンスはDOMツリーの一部ではありませんが、プロパティの動作を示すことができます。
19    $entityReference = new DOMEntityReference('myEntity');
20
21    echo "DOMEntityReferenceのnodeName: " . $entityReference->nodeName . PHP_EOL;
22    echo "DOMEntityReferenceのnodeType: " . $entityReference->nodeType . " (DOM_ENTITY_REFERENCE定数: " . DOM_ENTITY_REFERENCE . ")" . PHP_EOL;
23
24    // DOMEntityReference::nodeValue は常にNULLを返します。
25    // エンティティの内容を取得したい場合は、エンティティが展開された後のテキストノードを参照するか、
26    // DOMDocumentType::entities コレクションからDOMEntityノードを取得してその内容を解析する必要があります。
27    echo "DOMEntityReferenceのnodeValue: ";
28    if ($entityReference->nodeValue === null) {
29        echo "NULL" . PHP_EOL;
30    } else {
31        // この分岐には入らないはずですが、型ヒントに従って文字列として出力します。
32        echo "'" . $entityReference->nodeValue . "'" . PHP_EOL;
33    }
34}
35
36// 関数の実行
37demonstrateDomEntityReferenceNodeValue();

このサンプルコードは、PHPのDOM拡張機能に存在するDOMEntityReferenceクラスのnodeValueプロパティの挙動を説明しています。DOMEntityReferenceはXML文書内で宣言されたエンティティ(例: &nbsp;)への参照を表すノードですが、PHPのXMLパーサーは通常、これらの参照を自動的に展開してしまうため、DOMツリー上でこの種類のノードに直接出会う機会は稀です。

DOMEntityReference::nodeValueプロパティは、引数を持たず、戻り値としてstringまたはnullを返します。しかし、このプロパティにアクセスした場合、常にNULLが返されるという特性があります。これは、DOMEntityReferenceノード自体が具体的なテキスト値を持つわけではないためです。このプロパティは、エンティティ参照が指す内容そのもの(例えば、&amp;が表す&という文字)を直接取得する目的には使用できません。

もしエンティティ参照の具体的な内容を取得したい場合は、DOMツリー上でエンティティが展開された結果として生成されるテキストノードを参照するか、またはDOMDocumentTypeクラスのentitiesコレクションからDOMEntityノードを取得し、そのnodeValueプロパティや子ノードを調べる必要があります。DOMEntityReference::nodeValueが常にNULLを返すという点は、XML処理を行う上で理解しておくべき重要な挙動の一つです。

このサンプルコードで最も注意すべき点は、DOMEntityReference::nodeValueプロパティが常にnullを返すことです。XMLパーサーは通常、エンティティ参照を自動的に展開してしまうため、DOMEntityReferenceノードに直接遭遇する機会は稀です。もしこのノードに出会ったとしても、エンティティ参照そのものは値を持たないため、nodeValuenullとなります。エンティティの実際の内容を取得したい場合は、XMLが解析され展開された後のテキストノードを参照するか、DOMDocumentType::entitiesコレクションからDOMEntityノードを取得し、その内容を解析するようにしてください。DOMEntityReferenceは「参照が存在する」ことを示すものであり、その内容を取り出す目的には適しません。

関連コンテンツ

関連プログラミング言語

【PHP8.x】DOMEntityReference::nodeValueプロパティの使い方 | いっしー@Webエンジニア