【PHP8.x】DOMProcessingInstruction::nodeValueプロパティの使い方
nodeValueプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『nodeValueプロパティは、DOMProcessingInstructionオブジェクトが表す処理命令(Processing Instruction)の内容を文字列として保持するプロパティです。処理命令とは、XMLやHTML文書内において、文書を処理するアプリケーションに対する指示を記述するためのもので、<?target data?>という形式で表されます。このプロパティが保持するのは、処理命令のターゲット(target)を除いた内容(data)の部分です。例えば、<?php echo 'Hello'; ?>という処理命令がある場合、nodeValueプロパティは文字列echo 'Hello';を返します。一方で、処理命令のターゲットであるphpを取得するには、targetプロパティまたはnodeNameプロパティを使用します。このように、nodeValueプロパティは処理命令のデータ部分に特化しています。このプロパティは読み取りだけでなく書き込みも可能で、新しい文字列を代入することで処理命令の内容を動的に変更することができます。これにより、DOMを操作して処理命令の具体的な指示をプログラムから制御することが可能になります。』
構文(syntax)
1<?php 2// 処理命令を含むXML文字列を定義 3$xmlString = '<?xml version="1.0"?><?php-app version="1.0" theme="dark"?><root/>'; 4 5// DOMDocumentオブジェクトを作成し、XMLを読み込む 6$doc = new DOMDocument(); 7$doc->loadXML($xmlString); 8 9// 処理命令ノードを取得 (XML宣言の次のノード) 10// $pi は DOMProcessingInstruction オブジェクト 11$pi = $doc->childNodes[1]; 12 13// nodeValueプロパティで処理命令のコンテンツを取得して表示 14// 出力: version="1.0" theme="dark" 15echo $pi->nodeValue . PHP_EOL; 16 17// nodeValueプロパティに新しい値を代入してコンテンツを更新 18$pi->nodeValue = 'version="2.0" theme="light"'; 19 20// ドキュメント全体を文字列として出力し、変更を確認 21// 出力: <?xml version="1.0"?> 22// <?php-app version="2.0" theme="light"?><root/> 23echo $doc->saveXML(); 24?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMProcessingInstruction::nodeValue は、ProcessingInstruction ノードのデータ部分を表す文字列、またはデータがない場合は null を返します。
サンプルコード
PHP DOM: nodeValueとtextContentの比較
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOMNodeの `nodeValue` と `textContent` プロパティの違いを比較します。 7 * 8 * `nodeValue` と `textContent` は、特に「要素ノード」を扱う際に挙動が大きく異なります。 9 * このサンプルコードは、異なる種類のノードでそれぞれのプロパティがどのように振る舞うかを示します。 10 */ 11function demonstrateNodeValueVsTextContent(): void 12{ 13 // 比較対象のHTMLデータ 14 $html = <<<HTML 15 <div id="container"> 16 メインのテキスト 17 <!-- これはコメントです --> 18 <strong>太字のテキスト</strong> 19 <?php instruction-data ?> 20 </div> 21 HTML; 22 23 // DOMDocumentオブジェクトを生成し、HTMLを読み込む 24 $dom = new DOMDocument(); 25 // HTML5の要素などで発生する警告を抑制するために @ を使用 26 @$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 27 28 // XPathを使って各ノードを正確に取得する 29 $xpath = new DOMXPath($dom); 30 $elementNode = $xpath->query('//div')->item(0); 31 $textNode = $xpath->query('//div/text()[normalize-space()]')->item(0); 32 $commentNode = $xpath->query('//comment()')->item(0); 33 $piNode = $xpath->query('//processing-instruction()')->item(0); // DOMProcessingInstruction 34 35 // 1. 要素ノード (<div>) での比較 36 // これが nodeValue と textContent の最も重要な違いです。 37 echo "■ 1. 要素ノード (<div>) での比較:\n"; 38 // 要素ノード自体の値は存在しないため、nodeValue は常に null になります。 39 echo ' nodeValue: ' . json_encode($elementNode->nodeValue) . " (常に null)\n"; 40 // textContent は、その要素とすべての子孫ノードのテキストコンテンツを連結して返します。 41 // 分かりやすくするため、余分な空白はトリムして表示します。 42 echo ' textContent: "' . trim(preg_replace('/\s+/', ' ', $elementNode->textContent)) . "\"\n\n"; 43 44 // 2. テキストノードでの比較 45 echo "■ 2. テキストノード (\"メインのテキスト\") での比較:\n"; 46 // テキストノードの場合、nodeValue と textContent は同じテキスト内容を返します。 47 echo ' nodeValue: "' . trim($textNode->nodeValue) . "\"\n"; 48 echo ' textContent: "' . trim($textNode->textContent) . "\"\n\n"; 49 50 // 3. コメントノードでの比較 51 echo "■ 3. コメントノードでの比較:\n"; 52 // コメントノードの場合も、nodeValue と textContent は同じコメント内容を返します。 53 echo ' nodeValue: "' . trim($commentNode->nodeValue) . "\"\n"; 54 echo ' textContent: "' . trim($commentNode->textContent) . "\"\n\n"; 55 56 // 4. 処理命令ノード (DOMProcessingInstruction) での比較 57 echo "■ 4. 処理命令ノード (<?php ... ?>) での比較:\n"; 58 // 処理命令ノードの場合、nodeValue は命令のデータ部分を返します。textContent も同様です。 59 echo ' nodeValue: "' . trim($piNode->nodeValue) . "\"\n"; 60 echo ' textContent: "' . trim($piNode->textContent) . "\"\n"; 61} 62 63// 関数を実行して結果を表示 64demonstrateNodeValueVsTextContent(); 65 66?>
このPHPサンプルコードは、DOM操作において混同しやすいnodeValueとtextContentという2つのプロパティの挙動の違いを、様々な種類のノードを用いて具体的に比較し、解説するものです。特に、処理命令ノード(DOMProcessingInstruction)におけるnodeValueの役割に焦点を当てています。
コードではまず、HTML文字列からDOMオブジェクトを生成し、XPathを使って「要素ノード」「テキストノード」「コメントノード」「処理命令ノード」の4種類を取得します。
nodeValueとtextContentの最も大きな違いは「要素ノード」で現れます。要素ノード自体に直接的な値は存在しないため、nodeValueは常にnullを返します。一方、textContentはその要素が内包するすべての子孫ノードのテキストを連結した文字列を返します。
テキストノードやコメントノードでは、両プロパティは同じようにノード内のテキストやコメント内容を返します。そして、DOMProcessingInstructionのインスタンスである処理命令ノードの場合も同様に、nodeValueとtextContentは命令のデータ部分を文字列として返します。このnodeValueプロパティは引数を取らず、戻り値としてノードの内容である文字列、または該当する値がない場合はnullを返します。
このように、取得したい情報の種類や対象となるノードの種類に応じて、2つのプロパティを正しく使い分けることが重要です。
nodeValueとtextContentの最も重要な違いは、<div>のような要素ノードを扱う際の挙動です。初心者が間違いやすいのは、要素ノードのテキストを取得する目的でnodeValueを使い、常にnullが返されてしまうことです。要素とその子孫ノード全てのテキストをまとめて取得したい場合は、textContentを使用するのが正解です。一方、テキスト、コメント、そしてDOMProcessingInstructionのような処理命令ノードでは、両プロパティは基本的に同じ内容の文字列を返します。取得したい対象がタグで囲まれた要素全体か、個別のテキスト部分なのかを意識し、適切にプロパティを使い分けることが重要です。