【PHP8.x】DOMEntityReference::textContentプロパティの使い方
textContentプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
textContentプロパティは、エンティティ参照ノード(DOMEntityReference)とその子孫が持つテキスト内容を、文字列として保持するプロパティです。このプロパティが所属するDOMEntityReferenceクラスは、XMLやHTML文書内における&や©のようなエンティティ参照を表します。このプロパティにアクセスすると、エンティティ参照が展開された後のテキストデータを取得できます。例えば、文書内の©に対応するノードのtextContentを参照した場合、文字列「©」が得られます。このとき、タグなどのマークアップはすべて除去され、人間が読むのと同じ純粋なテキスト部分のみが返されるのが特徴です。また、このプロパティに新しい文字列を代入することで、ノードの内容を書き換えることもできます。値を設定すると、元のエンティティ参照ノードは、代入した文字列を内容とする新しいテキストノードに置き換えられます。このプロパティは親クラスであるDOMNodeから継承されており、DOMツリー内のテキスト情報を手軽に操作するために広く利用されます。
構文(syntax)
1<?php 2 3$dom = new DOMDocument(); 4$entity_reference_node = $dom->createEntityReference('example'); 5 6// DOMEntityReferenceオブジェクトのtextContentプロパティを取得します。 7// このプロパティの値は常にnullです。 8$text_content = $entity_reference_node->textContent; 9 10var_dump($text_content); 11 12?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMエンティティ参照ノードのテキストコンテンツを文字列で返します。ノードにテキストコンテンツがない場合はnullを返します。
サンプルコード
PHP DOMDocument textContentでエンティティ値を取得する
1<?php 2 3/** 4 * XML内のエンティティ参照からテキストコンテンツを取得するサンプル関数です。 5 * 6 * DOMDocumentを使用してXMLを解析し、DOMEntityReferenceノードにアクセスします。 7 * textContentプロパティは、エンティティ参照が表すテキスト(実体)を返します。 8 */ 9function getEntityReferenceTextContent(): void 10{ 11 // DTD(文書型定義)でエンティティ '&authorName;' を定義したXML文字列。 12 // このエンティティは 'Taro Yamada' というテキストを表します。 13 $xmlString = <<<XML 14 <?xml version="1.0" encoding="utf-8"?> 15 <!DOCTYPE book [ 16 <!ENTITY authorName "Taro Yamada"> 17 ]> 18 <book> 19 <author>&authorName;</author> 20 <title>PHP Programming</title> 21 </book> 22 XML; 23 24 // DOMDocumentオブジェクトをインスタンス化します 25 $dom = new DOMDocument(); 26 27 // DOMEntityReferenceノードを保持するために、エンティティの自動置換を無効にします。 28 // この設定がtrue(デフォルト)だと、'&authorName;'はパース時に'Taro Yamada'という 29 // テキストノードに置き換えられてしまい、DOMEntityReferenceノードは生成されません。 30 $dom->substituteEntities = false; 31 32 // XML文字列を読み込みます 33 $dom->loadXML($xmlString); 34 35 // <author>要素を取得します 36 $authorElement = $dom->getElementsByTagName('author')->item(0); 37 38 // <author>要素の最初の子ノード('&authorName;'を表すDOMEntityReferenceノード)を取得します 39 $entityRefNode = $authorElement->firstChild; 40 41 // ノードがDOMEntityReferenceのインスタンスであることを確認します 42 if ($entityRefNode instanceof DOMEntityReference) { 43 // textContentプロパティは、エンティティ参照の実体('Taro Yamada')を返します。 44 $content = $entityRefNode->textContent; 45 46 echo "エンティティ参照名: " . $entityRefNode->nodeName . PHP_EOL; 47 echo "textContent の値: " . $content . PHP_EOL; 48 } else { 49 echo "DOMEntityReference ノードが見つかりませんでした。" . PHP_EOL; 50 } 51} 52 53// 関数を実行します 54getEntityReferenceTextContent(); 55 56/* 57実行結果: 58エンティティ参照名: authorName 59textContent の値: Taro Yamada 60*/
PHPのDOMEntityReferenceクラスが持つtextContentプロパティは、XML文書内にあるエンティティ参照(例: &authorName;)が、実際に指し示しているテキスト内容を取得するために使用されます。このプロパティに引数はありません。
サンプルコードでは、DTD(文書型定義)で&authorName;というエンティティ参照が "Taro Yamada" という文字列を表すように定義されています。DOMEntityReferenceノードに対してtextContentプロパティを呼び出すと、その参照先である "Taro Yamada" という文字列が戻り値(string型)として返されます。テキストが存在しない場合はnullを返すことがあります。
このDOMEntityReferenceノードを取得するためには、事前にDOMDocumentオブジェクトのsubstituteEntitiesプロパティをfalseに設定する必要があります。この設定を行わないと、XMLの読み込み時にエンティティ参照が自動的にテキストに置き換えられてしまうため注意が必要です。textContentプロパティは、エンティティ参照が持つ具体的なテキストデータをプログラムで扱いたい場合に便利な機能です。
DOMEntityReferenceのtextContentプロパティを利用する際の最も重要な点は、XMLを読み込む前に$dom->substituteEntities = false;と設定することです。この設定がない場合、PHPはエンティティ参照(例:&authorName;)を自動的にただのテキスト(Taro Yamada)に置き換えてしまうため、エンティティ参照ノードそのものを取得できなくなります。また、textContentはエンティティが参照しているテキストの実体を返すのに対し、エンティティ名自体はnodeNameプロパティで取得します。安全に利用するため、loadXMLやノードを取得する処理では、対象が見つからない場合に備えて戻り値がnullやfalseでないかを確認することが重要です。
PHP DOM: nodeValue と textContent の違い
1<?php 2 3/** 4 * DOMNode の textContent と nodeValue プロパティの違いを比較します。 5 * 6 * textContent は、そのノードとすべての子孫のテキストを連結して返します。 7 * nodeValue は、ノードの種類によって挙動が異なり、要素ノード(DOMElement)では常に null です。 8 * 9 * このサンプルでは、指定された DOMEntityReference を含むXMLを例に、これらの違いを解説します。 10 */ 11function demonstrateNodeValueVsTextContent(): void 12{ 13 // エンティティ (&company;) を含むXML文字列を定義 14 $xmlString = <<<XML 15 <?xml version="1.0" encoding="UTF-8"?> 16 <!DOCTYPE root [ 17 <!ENTITY company "Awesome Inc."> 18 ]> 19 <root> 20 <p>Learn more at <b>&company;</b> official site.</p> 21 </root> 22 XML; 23 24 $dom = new DOMDocument(); 25 // エンティティ参照を DOMEntityReference ノードとして保持するために、 26 // LIBXML_NOENT オプションは指定しません。 27 $dom->loadXML($xmlString); 28 $xpath = new DOMXPath($dom); 29 30 // 1. DOMEntityReference ノード (&company;) を取得 31 $entityRefNode = $xpath->query('//b')->item(0)->firstChild; 32 33 echo "--- 1. DOMEntityReference ノード (&company;) ---\n"; 34 // DOMEntityReference 自体の nodeValue と textContent は null を返します。 35 echo 'nodeValue: '; 36 var_dump($entityRefNode->nodeValue); 37 echo 'textContent: '; 38 var_dump($entityRefNode->textContent); 39 echo "\n"; 40 41 // 2. 親である <b> 要素ノードを取得 42 $bElement = $entityRefNode->parentNode; 43 44 echo "--- 2. 親の <b> 要素ノード ---\n"; 45 // 要素ノードの nodeValue は常に null です。 46 echo 'nodeValue: '; 47 var_dump($bElement->nodeValue); 48 // textContent は子孫のテキストを連結するため、エンティティが展開された値が返ります。 49 echo 'textContent: '; 50 var_dump($bElement->textContent); 51 echo "\n"; 52 53 // 3. さらにその親である <p> 要素ノードを取得 54 $pElement = $bElement->parentNode; 55 56 echo "--- 3. さらに親の <p> 要素ノード ---\n"; 57 // 要素ノードなので nodeValue は同様に null です。 58 echo 'nodeValue: '; 59 var_dump($pElement->nodeValue); 60 // textContent は、すべての子孫のテキストを連結した文字列を返します。 61 echo 'textContent: '; 62 var_dump($pElement->textContent); 63 echo "\n"; 64} 65 66demonstrateNodeValueVsTextContent();
DOMEntityReferenceクラスのtextContentプロパティは、ノードとそのすべての子孫が持つテキストを連結した文字列を返します。このプロパティに引数はなく、戻り値はテキストコンテンツを表す文字列、またはテキストが存在しない場合はnullです。
サンプルコードでは、XML内のエンティティ参照&company;(DOMEntityReferenceノード)と、その親要素におけるtextContentとnodeValueの挙動の違いを示しています。
DOMEntityReferenceノード自体に対してtextContentとnodeValueを取得すると、どちらもnullが返されます。これは、エンティティ参照ノードが直接テキスト情報を持たないためです。
一方、親である<b>要素のtextContentを取得すると、子であるエンティティ&company;が展開された値「Awesome Inc.」が文字列として返されます。さらに親の<p>要素では、周囲のテキストと連結された「Learn more at Awesome Inc. official site.」という文字列が得られます。
これに対し、nodeValueプロパティは、<b>や<p>のような要素ノードに対しては常にnullを返します。このようにtextContentは、要素が内包するすべてのテキストをまとめて取得したい場合に非常に便利なプロパティです。
nodeValueとtextContentは似ていますが、挙動が異なるため注意が必要です。HTMLタグなどの要素ノードからテキストを取得したい場合、nodeValueプロパティは常にnullを返します。これは仕様であり、間違いではありません。要素が持つテキスト内容をすべて取得するにはtextContentプロパティを使用してください。textContentは、その要素だけでなく、すべての子や孫要素に含まれるテキストを連結した一つの文字列として返します。サンプルコードのように、XMLエンティティ参照ノード自体の値はnullですが、その親要素のtextContentを参照することで、展開された文字列を取得できます。XMLを読み込む際のオプション指定によっても挙動が変わるため、ドキュメントの確認が重要です。