【PHP8.x】nodeValueプロパティの使い方
nodeValueプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
nodeValueプロパティは、DOMElementノードの値を保持するプロパティです。DOMElementは、XMLドキュメントやHTMLドキュメントにおける要素(タグ)を表すオブジェクトであり、nodeValueプロパティを通じて、その要素が持つテキストコンテンツを取得または設定できます。
具体的には、要素ノードがテキストノード(例えば <p>This is text.</p> の This is text. の部分)を持っている場合、nodeValueプロパティはそのテキストノードの値を返します。要素ノード自体が直接テキストノードを持っていない場合、nodeValueプロパティは通常 null を返します。
nodeValueプロパティは、文字列を代入することで要素のテキストコンテンツを更新することも可能です。ただし、この操作は要素の子ノードを全て削除し、新しいテキストノードとして代入された文字列を追加する形で行われます。したがって、要素が既に複数の子ノード(テキストノード、要素ノードなど)を持っている場合、それらは全て削除されることに注意が必要です。
このプロパティは、DOMを操作してドキュメントの内容を動的に変更する際に非常に重要です。例えば、フォームの入力値を読み取って特定の要素に表示したり、データベースから取得したデータをHTMLドキュメントに挿入したりする際に活用できます。
要素のテキストコンテンツを安全に操作するためには、textContentプロパティや、createTextNodeメソッドなど、他の関連するDOM APIと組み合わせて使用することを推奨します。特に、HTMLエンティティのエスケープ処理が必要な場合は、textContentプロパティを使用すると安全です。
構文(syntax)
1<?php 2$dom = new DOMDocument(); 3$element = $dom->createElement('example', 'Original Text'); 4 5// DOMElement オブジェクトの nodeValue プロパティを読み取る 6$currentValue = $element->nodeValue; 7 8// DOMElement オブジェクトの nodeValue プロパティに新しい値を代入する 9$element->nodeValue = 'New Text'; 10?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
string|null
DOMElement オブジェクトのテキストコンテンツ、または属性値の文字列を返します。ノードがテキストノードや属性ノードでない場合は null を返します。
サンプルコード
PHP: nodeValueとtextContentを比較する
1<?php 2 3/** 4 * DOMElementのnodeValueとtextContentプロパティの違いをデモンストレーションする関数。 5 * 6 * この関数は、HTML/XMLドキュメントからテキストコンテンツを取得する際に、 7 * DOMElement::nodeValue と DOMElement::textContent がどのように異なる結果を返すかを 8 * システムエンジニアを目指す初心者にも分かりやすく示します。 9 */ 10function demonstrateDomTextProperties(): void 11{ 12 // 比較のためのHTMLドキュメント文字列を準備します。 13 $html = <<<HTML 14 <!DOCTYPE html> 15 <html> 16 <head> 17 <title>DOM Text Properties Example</title> 18 </head> 19 <body> 20 <div id="container"> 21 これは<b>強調された</b>テキストです。<br> 22 <span>さらに別の</span>テキスト行。 23 <!-- これはコメントノードです --> 24 </div> 25 <p id="simple-text">シンプルなテキストです。</p> 26 <span id="empty-span"></span> 27 </body> 28 </html> 29 HTML; 30 31 // DOMDocumentオブジェクトを初期化し、HTMLをロードします。 32 // @ を使用して、HTMLの潜在的な構文エラーによる警告を抑制します。 33 // LIBXML_NOCDATA は、CDATAセクションを通常のテキストノードとして扱います。 34 $dom = new DOMDocument(); 35 @$dom->loadHTML($html, LIBXML_NOCDATA); 36 37 echo "DOMElement::nodeValue と DOMElement::textContent の比較\n"; 38 echo "-----------------------------------------------------\n\n"; 39 40 // 1. id="container" のdiv要素を検証 41 $containerElement = $dom->getElementById('container'); 42 if ($containerElement instanceof DOMElement) { 43 echo "■ 要素: <div id=\"container\">\n"; 44 echo " - nodeName: " . $containerElement->nodeName . "\n"; 45 // DOMElement::nodeValue は、通常、要素ノード自身に対しては null を返します。 46 // 子テキストノードの値を取得する目的ではあまり使用されません。 47 echo " - nodeValue: '" . ($containerElement->nodeValue ?? 'null (要素ノードは通常null)') . "'\n"; 48 // DOMElement::textContent は、要素とそのすべての子孫ノード(テキストノード、CDATAなど)の 49 // テキストコンテンツを結合して返します。タグやコメントは無視されます。 50 echo " - textContent: '" . $containerElement->textContent . "'\n\n"; 51 } 52 53 // 2. id="simple-text" のp要素を検証 54 $pElement = $dom->getElementById('simple-text'); 55 if ($pElement instanceof DOMElement) { 56 echo "■ 要素: <p id=\"simple-text\">\n"; 57 echo " - nodeName: " . $pElement->nodeName . "\n"; 58 echo " - nodeValue: '" . ($pElement->nodeValue ?? 'null (要素ノードは通常null)') . "'\n"; 59 echo " - textContent: '" . $pElement->textContent . "'\n\n"; 60 } 61 62 // 3. <b>要素(id="container"の子)を検証 63 // DOMXPathを使って、最初に見つかった<b>要素を取得します。 64 $xpath = new DOMXPath($dom); 65 $bElements = $xpath->query('//b'); 66 if ($bElements->length > 0) { 67 $bElement = $bElements->item(0); 68 if ($bElement instanceof DOMElement) { 69 echo "■ 要素: <b> (強調されたテキスト)\n"; 70 echo " - nodeName: " . $bElement->nodeName . "\n"; 71 echo " - nodeValue: '" . ($bElement->nodeValue ?? 'null (要素ノードは通常null)') . "'\n"; 72 echo " - textContent: '" . $bElement->textContent . "'\n\n"; 73 } 74 } 75 76 // 4. 空の<span>要素を検証 77 $emptySpanElement = $dom->getElementById('empty-span'); 78 if ($emptySpanElement instanceof DOMElement) { 79 echo "■ 要素: <span id=\"empty-span\">\n"; 80 echo " - nodeName: " . $emptySpanElement->nodeName . "\n"; 81 echo " - nodeValue: '" . ($emptySpanElement->nodeValue ?? 'null (要素ノードは通常null)') . "'\n"; 82 echo " - textContent: '" . $emptySpanElement->textContent . "'\n\n"; 83 } 84 85 // 5. テキストノードを直接検証 (比較のため) 86 // "シンプルなテキストです。" というテキストノード自体を探します。 87 // まず、<p>要素を取得し、その最初の子ノードがテキストノードであると仮定します。 88 $pTextNode = null; 89 if ($pElement instanceof DOMElement && $pElement->firstChild instanceof DOMNode) { 90 if ($pElement->firstChild->nodeType === XML_TEXT_NODE) { 91 $pTextNode = $pElement->firstChild; 92 } 93 } 94 95 if ($pTextNode instanceof DOMNode) { 96 echo "■ ノード: #text (直接のテキストノード)\n"; 97 echo " - nodeName: " . $pTextNode->nodeName . "\n"; // テキストノードの場合、#textを返す 98 // テキストノードのnodeValueは、そのノードが持つ実際のテキストコンテンツです。 99 echo " - nodeValue: '" . $pTextNode->nodeValue . "'\n"; 100 // テキストノードのtextContentも、そのノードが持つ実際のテキストコンテンツです。 101 echo " - textContent: '" . $pTextNode->textContent . "'\n\n"; 102 } 103} 104 105// デモンストレーション関数を実行します。 106demonstrateDomTextProperties();
PHP 8のDOMElement::nodeValueは、DOMツリー内のノードの値を文字列として取得するプロパティです。このプロパティは引数を取らず、値が存在する場合は文字列を、存在しない場合はnullを返します。通常、divやpのような要素ノード自身に対してはnullを返しますが、テキストノードやコメントノードのような特定のノードタイプではその内容を直接返します。
このサンプルコードは、DOMElement::nodeValueとDOMElement::textContentの違いを比較しています。nodeValueが要素ノードに対してはnullを返すことが多いのに対し、textContentは要素とそのすべての子孫ノードから、タグやコメントを除いた純粋なテキストコンテンツをすべて結合して返します。例えば、<div id="container">のような、複数のタグやテキスト、コメントを含む要素に対してnodeValueを適用してもnullになる一方、textContentではそのdiv内にあるすべてのテキストがまとめて取得されます。一方、直接的なテキストノードに対しては、nodeValueとtextContentは同じテキスト内容を返します。要素内の目に見えるテキストをまとめて取得したい場合はtextContent、特定のノードの直接的な値を取得したい場合はnodeValueと使い分けることが重要です。
DOMElementのnodeValueとtextContentプロパティは、テキスト取得の際に異なる挙動を示します。nodeValueは要素ノード自体ではほとんどの場合nullを返しますが、テキストノードや属性ノードなど特定の種類のノードに対してはその内容を返します。一方、textContentは、要素とそのすべての子孫ノードからタグやコメントを除いた、視覚的に表示されるテキストコンテンツを結合して取得します。要素内部のテキストをまとめて抽出したい場合はtextContentを使用するのが一般的です。特定のテキストノードや属性ノードの直接的な値が必要な場合にnodeValueを検討してください。要素ノードにnodeValueを使っても期待するテキストは得られない点にご注意ください。