【PHP8.x】Dom\Entity::nodeValueプロパティの使い方
nodeValueプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
nodeValueプロパティは、Dom\Entityクラスに属し、ノードの値を保持するプロパティです。Dom\Entityクラスは、XMLやHTMLのDTD(Document Type Definition)で定義される「実体(エンティティ)」を表します。実体とは、文書内で頻繁に使用されるテキストや特殊文字などを名前で参照できるように定義し、再利用性を高めるための仕組みです。
このnodeValueプロパティは、通常、ノードのテキストコンテンツを取得するために使用されますが、Dom\Entityインスタンスに対してこのプロパティを参照すると、常にnullを返します。これは、DOM(Document Object Model)の仕様上、実体ノード自体が直接的なテキスト値を持つわけではないためです。実体は、その参照箇所で別のコンテンツに「置き換えられる」ものであり、実体ノードそのものが特定の値を保持する役割ではありません。
したがって、Dom\Entityオブジェクトから実体の実際のコンテンツ(置換テキスト)を取得するためには、このnodeValueプロパティではなく、実体の持つ内容にアクセスするための別のプロパティやメソッドを利用する必要があります。このnodeValueプロパティは読み取り専用であり、値を設定することはできません。
構文(syntax)
1<?php 2 3// Dom\Document を作成し、DTDでエンティティを定義します。 4$dom = new Dom\Document(); 5$dom->loadXML('<?xml version="1.0"?> 6<!DOCTYPE doc [ 7 <!ENTITY myEntity "Some Entity Text"> 8]> 9<root/>'); 10 11// DTDから "myEntity" という名前の Dom\Entity ノードを取得します。 12// Dom\Entity は直接インスタンス化できないため、このようにして取得します。 13$entityNode = $dom->doctype->entities->getNamedItem('myEntity'); 14 15// Dom\Entity の nodeValue プロパティにアクセスする構文です。 16// Dom\Entity の nodeValue は常に NULL を返します。 17$value = $entityNode->nodeValue; 18 19?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
このプロパティは、ノードのテキストコンテンツを表す文字列、またはノードにテキストコンテンツがない場合はnullを返します。
サンプルコード
nodeValueとtextContentの違いを理解する
1<?php 2 3/** 4 * DOMNodeのnodeValueとtextContentプロパティの違いを比較して表示します。 5 * 6 * `nodeValue` と `textContent` は、どちらもノードに関連するテキストを取得しますが、 7 * どのノードから値を取得するかによって挙動が大きく異なります。 8 * このサンプルコードは、その違いを明確に示します。 9 */ 10function demonstrateNodeValueVsTextContent(): void 11{ 12 // 比較用のXML文字列を準備 13 $xmlString = <<<XML 14 <?xml version="1.0" encoding="UTF-8"?> 15 <article> 16 <title>PHPの基本</title> 17 <content> 18 これは本文です。<b>重要</b>な部分も含まれます。 19 </content> 20 <!-- 2023-10-27 draft --> 21 </article> 22 XML; 23 24 // DOMDocumentオブジェクトを作成し、XMLを読み込む 25 $dom = new DOMDocument(); 26 $dom->loadXML($xmlString); 27 28 // --- 比較1: 子要素を持つ要素ノード (<content>) --- 29 // <content>要素は、内部にテキストノードと<b>要素を持っています。 30 $contentElement = $dom->getElementsByTagName('content')->item(0); 31 32 echo "■ 1. 子要素を持つ要素ノード (<content>) での比較:" . PHP_EOL; 33 34 // `nodeValue`は、要素ノード(Element)自体にはテキスト値を持たないため、常にnullを返します。 35 printf( 36 " - nodeValue: %s (要素ノード自体は値を持たないため)\n", 37 json_encode($contentElement->nodeValue) 38 ); 39 40 // `textContent`は、そのノードと、そのすべての子孫ノードのテキストを連結して返します。 41 // この場合、「これは本文です。」「重要」「な部分も含まれます。」が連結されます。 42 printf( 43 " - textContent: %s (子孫のテキストもすべて連結される)\n", 44 json_encode(trim(preg_replace('/\s+/', ' ', $contentElement->textContent))) 45 ); 46 47 echo PHP_EOL; 48 49 // --- 比較2: テキストノード (<title>の中身) --- 50 // <title>要素の最初の子ノードであるテキストノード「PHPの基本」を取得します。 51 $titleTextNode = $dom->getElementsByTagName('title')->item(0)->firstChild; 52 53 echo "■ 2. テキストノード (「PHPの基本」) での比較:" . PHP_EOL; 54 55 // テキストノードやコメントノードの場合、`nodeValue`と`textContent`は同じ値を返します。 56 printf( 57 " - nodeValue: %s\n", 58 json_encode($titleTextNode->nodeValue) 59 ); 60 printf( 61 " - textContent: %s\n", 62 json_encode($titleTextNode->textContent) 63 ); 64} 65 66// 関数を実行して結果を表示します 67demonstrateNodeValueVsTextContent();
Dom\EntityクラスのnodeValueプロパティは、DOMツリー内のノードが持つ値を取得するために使用します。このプロパティに引数はなく、ノードの種類に応じてその値の文字列、または値を持たない場合はnullを返します。
nodeValueの挙動を理解するには、よく似たtextContentプロパティとの違いを知ることが重要です。サンプルコードの<content>のような要素ノードに対してnodeValueを使用すると、要素ノード自体はテキスト値を持たないため、常にnullが返されます。一方、textContentは、その要素が内包するすべての子孫ノードのテキストを連結した文字列を返します。
これに対して、サンプルコードの<title>内の「PHPの基本」のようなテキストノードの場合、nodeValueとtextContentはどちらも同じ挙動を示し、そのノードが持つテキスト文字列そのものを返します。
このようにnodeValueは、テキストノードやコメントノードなど、それ自体が固有の値を持つ特定のノードから直接値を取得する際に利用します。要素全体のテキストを構造を無視して取得したい場合はtextContentが適しています。
nodeValueプロパティは、扱うノードの種類によって挙動が大きく変わる点に注意が必要です。サンプルコードの<content>のような要素ノード(タグ)に対してnodeValueを使用すると、常にnullが返されます。これは要素ノード自体がテキスト値を持たないためで、初心者がテキストを取得する際に間違いやすいポイントです。一方、テキストノードやコメントノードに対しては、その内容の文字列を返します。タグ内の子要素も含めた全てのテキストをまとめて取得したい場合はtextContentを、特定のテキストノードの値だけが必要な場合はnodeValueを使う、という使い分けを意識しましょう。nodeValueはnullを返す可能性があるため、取得した値を利用する前にはnullチェックを行うと、より安全なコードになります。