【PHP8.x】DOMDocument::childNodesプロパティの使い方
childNodesプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
childNodesプロパティは、DOMDocumentクラスに属する、ドキュメントの直接の子ノードを保持するプロパティです。具体的には、DOMNodeListオブジェクトとして提供されます。DOMNodeListは、ノードの順番付きのリストであり、インデックスを使用して各ノードにアクセスできます。
このプロパティを使用することで、DOMドキュメントのルート要素(通常は<html>タグ)や、ドキュメントタイプ宣言(<!DOCTYPE>)などの子ノードをプログラムから操作することが可能になります。例えば、ドキュメントの構造を解析したり、新しいノードを挿入する場所を特定したりする際に役立ちます。
childNodesプロパティが返すDOMNodeListは、ライブリストであることに注意が必要です。つまり、DOMツリーが変更されると、DOMNodeListの内容も自動的に更新されます。したがって、DOMNodeListを反復処理中にノードを追加または削除すると、予期しない動作が発生する可能性があります。このような場合は、事前にノードリストを配列にコピーしてから処理を行うなどの対策が必要です。
DOMDocumentのchildNodesプロパティを通じて取得できるノードの種類には、DOMElement(要素ノード)、DOMText(テキストノード)、DOMComment(コメントノード)などがあります。ただし、属性ノードは含まれません。属性は要素ノードのプロパティとしてアクセスされます。
システムエンジニアを目指す上で、DOMDocumentのchildNodesプロパティは、XMLやHTMLドキュメントをPHPで操作する際の基礎となる重要な概念です。このプロパティを理解し、効果的に活用することで、Webアプリケーション開発におけるデータ処理や動的なコンテンツ生成をより柔軟に行うことができるようになります。
構文(syntax)
1DOMDocument::$childNodes;
引数(parameters)
引数なし
引数はありません
戻り値(return)
DOMNodeList
DOMDocument オブジェクトの直下にある子ノードのリストを DOMNodeList オブジェクトとして返します。
サンプルコード
PHP DOM childNodesで子ノードを取得する
1<?php 2 3// DOMDocument を作成 4$dom = new DOMDocument(); 5 6// XML 文字列をロード 7$dom->loadXML('<root><child1>value1</child1><child2>value2</child2></root>'); 8 9// childNodes プロパティを使用して、ルート要素の子ノードリストを取得 10$childNodes = $dom->documentElement->childNodes; 11 12// 子ノードをループして出力 13foreach ($childNodes as $childNode) { 14 // テキストノード以外を出力 15 if ($childNode->nodeType != XML_TEXT_NODE) { 16 echo $childNode->nodeName . PHP_EOL; 17 } 18} 19 20?>
PHP 8 における DOMDocument クラスの childNodes プロパティについて解説します。このプロパティは、特定のノード(この例ではドキュメントのルート要素)が持つ子ノードのリストを取得するために使用されます。
サンプルコードでは、まず DOMDocument オブジェクトを生成し、loadXML() メソッドを使ってXML文字列を読み込んでいます。次に、documentElement プロパティでドキュメントのルート要素にアクセスし、その childNodes プロパティにアクセスします。
childNodes プロパティは DOMNodeList オブジェクトを返します。このオブジェクトは、ルート要素直下のすべての子ノード(要素ノード、テキストノードなど)を含むリストです。
サンプルコードでは、取得した子ノードリストを foreach ループで処理し、各子ノードの nodeName プロパティを出力しています。ただし、nodeType プロパティが XML_TEXT_NODE でない場合のみ出力することで、テキストノード(空白や改行など)を除外しています。これにより、XML構造を構成する要素名のみを表示できます。
childNodes プロパティを使用することで、XMLドキュメント内の特定要素の子要素を簡単に取得し、操作することが可能になります。DOMNodeList はイテレータブルなオブジェクトなので、foreach ループなどで容易にアクセスできます。
childNodes は DOMElement の子ノード全てを含む DOMNodeList を返します。テキストノード(空白や改行など)も含まれるため、不要なノードを処理しないように nodeType で種類を判別する必要があります。サンプルコードでは XML_TEXT_NODE 以外のノードを出力しています。documentElement が null でないことを確認してから childNodes にアクセスしてください。また、DOMNodeList はライブリストであるため、リストをループ中にノードを追加・削除すると予期せぬ結果になることがあります。必要に応じて、事前に配列にコピーしてから処理することを検討してください。
PHP DOMDocument::childNodes プロパティを理解する
1<?php 2 3/** 4 * DOMDocument::childNodes プロパティの使用例を示します。 5 * 6 * この関数はHTML文字列をパースし、DOMDocumentオブジェクトの直接の子ノードを列挙します。 7 * システムエンジニアを目指す初心者向けに、DOMツリーの基本的な構造と 8 * childNodesプロパティの動作を理解しやすく作成されています。 9 */ 10function demonstrateDomChildNodes(): void 11{ 12 // 新しいDOMDocumentオブジェクトを作成します。 13 $dom = new DOMDocument(); 14 15 // 厳密なエラーチェックを有効にします (推奨)。 16 // これにより、HTMLパースエラーが警告ではなく、エラーとして扱われるようになります。 17 $dom->strictErrorChecking = true; 18 19 // 読み込むHTML文字列を定義します。 20 // PHPのDOMDocument::loadHTML()はHTMLパーサーとして動作するため、 21 // <!DOCTYPE html>宣言は通常 $dom->doctype プロパティでアクセスされ、 22 // $dom->childNodes プロパティには通常、単一の <html> 要素ノードが含まれます。 23 $htmlString = <<<HTML 24<!DOCTYPE html> 25<html> 26<head> 27 <title>サンプルページ</title> 28</head> 29<body> 30 <!-- これはコメントです --> 31 <h1>PHP DOMDocumentのchildNodesプロパティ</h1> 32 <p>このページはDOM構造のデモンストレーション用です。</p> 33</body> 34</html> 35HTML; 36 37 // HTML文字列をDOMDocumentにロードします。 38 // 失敗した場合、警告が発生し、falseが返されます。 39 if (!$dom->loadHTML($htmlString)) { 40 echo "エラー: HTMLのロードに失敗しました。\n"; 41 return; 42 } 43 44 echo "--- DOMDocumentの直接の子ノード ---\n"; 45 echo "(PHPのDOMDocument::loadHTML()では、通常<html>要素のみが直接の子ノードとして現れます。)\n\n"; 46 47 // DOMDocumentのchildNodesプロパティにアクセスします。 48 // これはDOMNodeListオブジェクトを返します。 49 $childNodes = $dom->childNodes; 50 51 // DOMNodeListはTraversableインターフェースを実装しているため、foreachで反復処理できます。 52 // 各ノードについて、その種類と名前を表示します。 53 if ($childNodes->length === 0) { 54 echo "DOMDocumentに直接の子ノードは見つかりませんでした。\n"; 55 } else { 56 foreach ($childNodes as $index => $node) { 57 echo sprintf("ノード %d:\n", $index + 1); 58 echo sprintf(" 名前: %s\n", $node->nodeName); 59 echo sprintf(" タイプ: %s (%d)\n", NodeTypeToString($node->nodeType), $node->nodeType); 60 // テキストノードやコメントノードの場合、その内容の冒頭部分を表示します。 61 // DOMDocumentの直接の子では通常これらは現れませんが、一般的なノード情報として含めています。 62 if (in_array($node->nodeType, [XML_TEXT_NODE, XML_COMMENT_NODE])) { 63 $value = trim($node->nodeValue); 64 // 長すぎる値は省略 65 if (mb_strlen($value) > 50) { 66 $value = mb_substr($value, 0, 50) . '...'; 67 } 68 echo sprintf(" 値: %s\n", $value); 69 } 70 echo "\n"; 71 } 72 } 73 74 // 参考: DOCTYPEノードは $dom->doctype プロパティでアクセスできます。 75 if ($dom->doctype) { 76 echo "--- DOCTYPE情報 ---\n"; 77 echo sprintf(" 名前: %s\n", $dom->doctype->nodeName); 78 echo sprintf(" 公開識別子: %s\n", $dom->doctype->publicId ?: "(なし)"); 79 echo sprintf(" システム識別子: %s\n", $dom->doctype->systemId ?: "(なし)"); 80 echo "\n"; 81 } 82 83 // 参考: HTML文書のルート要素(<html>)にアクセスするには、documentElementプロパティを使用します。 84 // その子ノードを調べることで、<head>や<body>などの要素を見ることができます。 85 if ($dom->documentElement) { 86 echo "--- ルート要素 (<html>) の情報 ---\n"; 87 echo sprintf(" 名前: %s\n", $dom->documentElement->nodeName); 88 echo sprintf(" タイプ: %s (%d)\n", NodeTypeToString($dom->documentElement->nodeType), $dom->documentElement->nodeType); 89 echo sprintf(" 直接の子ノード数: %d\n", $dom->documentElement->childNodes->length); 90 echo "\n"; 91 } 92 93 echo "-------------------------------------\n"; 94} 95 96/** 97 * DOMノードタイプ定数を可読な文字列に変換するヘルパー関数。 98 * 99 * @param int $nodeType DOMノードタイプ定数(例: XML_ELEMENT_NODE) 100 * @return string ノードタイプを表す文字列 101 */ 102function NodeTypeToString(int $nodeType): string 103{ 104 switch ($nodeType) { 105 case XML_ELEMENT_NODE: return "要素ノード"; 106 case XML_ATTRIBUTE_NODE: return "属性ノード"; 107 case XML_TEXT_NODE: return "テキストノード"; 108 case XML_CDATA_SECTION_NODE: return "CDATAセクションノード"; 109 case XML_ENTITY_REF_NODE: return "エンティティ参照ノード"; 110 case XML_ENTITY_NODE: return "エンティティノード"; 111 case XML_PI_NODE: return "処理命令ノード"; 112 case XML_COMMENT_NODE: return "コメントノード"; 113 case XML_DOCUMENT_NODE: return "ドキュメントノード"; 114 case XML_DOCUMENT_TYPE_NODE: return "ドキュメントタイプノード"; 115 case XML_DOCUMENT_FRAG_NODE: return "ドキュメントフラグメントノード"; 116 case XML_NOTATION_NODE: return "記法ノード"; 117 case XML_DTD_NODE: return "DTDノード"; // XML_DOCUMENT_TYPE_NODE と同じ意味で使用されることも 118 default: return "不明なノードタイプ"; 119 } 120} 121 122// 関数を実行してデモンストレーションを開始します。 123demonstrateDomChildNodes(); 124 125?>
PHPのDOMDocument::childNodesプロパティは、HTMLやXML文書の構造をプログラムで操作する際に利用される、DOMDocumentオブジェクトの直接の子ノードのリストを取得するためのプロパティです。このプロパティは引数を取りません。戻り値としては、DOMNodeListオブジェクトを返します。DOMNodeListは、取得された子ノードを順序付けて含むリストであり、foreachループなどを用いて個々のノードにアクセスし、その情報を参照したり操作したりできます。
サンプルコードでは、HTML文字列をDOMDocumentオブジェクトにロードした後、$dom->childNodesプロパティにアクセスして直接の子ノードのリストを取得しています。PHPでDOMDocument::loadHTML()メソッドを使ってHTMLをパースした場合、通常DOMDocumentの直接の子ノードとして現れるのは、HTML文書全体のルート要素である<html>要素ノードのみです。コードでは、取得したDOMNodeListを一つずつ確認し、各ノードの名前やタイプ(要素ノード、テキストノードなど)を表示することで、DOMツリーの基本的な構造と、文書の最上位の子ノードへのアクセス方法を示しています。このプロパティは、DOMツリーを探索する上での起点として役立ちます。
DOMDocument::childNodesプロパティは、ドキュメントの直接の子ノードのリストを返します。loadHTML()でHTML文字列を読み込む場合、通常は<html>要素ノードが唯一の直接の子となります。<!DOCTYPE html>宣言は$dom->doctypeプロパティで、HTML内のコメントなどは<html>要素内の子ノードとしてアクセスする必要がある点に注意してください。予期せぬパースエラーを防ぐため、$dom->strictErrorCheckingをtrueに設定し、loadHTML()の戻り値を常に確認する習慣をつけましょう。返されるDOMNodeListはforeachで簡単に反復処理できます。
PHP DOMDocument childNodes を使った子ノード取得
1<?php 2 3/** 4 * PHPのDOMDocumentクラスにおけるchildNodesプロパティの使用例を示します。 5 * DOMDocument::childNodesは、ドキュメントの直接の子ノードのリスト(DOMNodeList)を返します。 6 * このサンプルでは、簡単なHTMLドキュメントをパースし、その直接の子ノードを列挙します。 7 */ 8function demonstrateDomChildNodes(): void 9{ 10 // 解析するシンプルなHTML文字列 11 $htmlString = <<<HTML 12<!DOCTYPE html> 13<html> 14<head> 15 <title>サンプルドキュメント</title> 16</head> 17<body> 18 <p>これはテスト段落です。</p> 19</body> 20</html> 21HTML; 22 23 // DOMDocumentオブジェクトを初期化 24 $dom = new DOMDocument(); 25 26 // HTML文字列をDOMDocumentにロードします。 27 // loadHTML()メソッドはHTMLの構文エラーに関する警告を生成する場合がありますが、 28 // このサンプルでは簡潔さのため、@演算子で警告を抑制しています。 29 @$dom->loadHTML($htmlString); 30 31 echo "DOMDocument::childNodesプロパティで取得した子ノード一覧:" . PHP_EOL; 32 echo "---------------------------------------------------" . PHP_EOL; 33 34 // DOMDocumentの直接の子ノードリストを取得します。 35 // このリストには通常、DOCTYPE宣言ノードと、HTMLのルート要素(<html>)が含まれます。 36 $childNodes = $dom->childNodes; 37 38 // 取得したDOMNodeListをループして、各ノードの情報を表示します。 39 foreach ($childNodes as $node) { 40 echo "ノード名: " . $node->nodeName; 41 echo ", ノードタイプ: " . $node->nodeType; 42 43 // ノードタイプ定数を使用して、より分かりやすい説明を追加します。 44 switch ($node->nodeType) { 45 case DOM_ELEMENT_NODE: 46 echo " (要素ノード)"; 47 break; 48 case DOM_DOCUMENT_TYPE_NODE: 49 echo " (DOCTYPE宣言ノード)"; 50 break; 51 case DOM_TEXT_NODE: 52 echo " (テキストノード)"; 53 break; 54 case DOM_COMMENT_NODE: 55 echo " (コメントノード)"; 56 break; 57 default: 58 echo " (その他のノードタイプ)"; 59 break; 60 } 61 echo PHP_EOL; 62 } 63 64 echo "---------------------------------------------------" . PHP_EOL; 65 echo "補足: DOMDocument::childNodesは、ドキュメント自体の直接の子ノードを返します。" . PHP_EOL; 66 echo "HTMLドキュメントの場合、通常はDOCTYPE宣言と<html>要素がこれにあたります。" . PHP_EOL; 67 echo "例えば<body>内の要素などを取得するには、<html>要素の子ノードを辿る必要があります。" . PHP_EOL; 68} 69 70// 関数を実行します。 71demonstrateDomChildNodes(); 72
PHPのDOMDocument::childNodesプロパティは、HTMLやXMLドキュメントの構造を操作する際に使用されます。このプロパティは、DOMDocumentオブジェクトが表すドキュメント自体の直接の子ノードすべてをリストとして取得するものです。
引数は不要で、呼び出すだけでDOMNodeListという形式のノードの集合を返します。DOMNodeListは配列のように繰り返し処理が可能で、各ノードはDOMNodeオブジェクトとして扱われます。これにより、それぞれのノード名やノードタイプなどの詳細情報を確認できます。
サンプルコードでは、まずシンプルなHTML文字列をDOMDocumentに読み込みます。次に、$dom->childNodesによって、このHTMLドキュメントの直接の子ノードを取得しています。HTMLドキュメントの場合、通常は<!DOCTYPE html>のようなDOCTYPE宣言ノードと、ドキュメントのルート要素である<html>要素がこれにあたります。取得したノードリストをループ処理で順に表示することで、各ノードの名前と種類が具体的にどのように取得できるかを示しています。
このプロパティは、あくまで「ドキュメントの直接の子ノード」を対象とするため、例えば<html>要素の中にある<body>や<p>のようなさらに深い階層のノードは直接は取得できません。それらのノードにアクセスするには、取得した<html>要素のchildNodesをさらに辿るか、XPathなどのより高度な方法を用いる必要があります。
このサンプルコードでは、@演算子を使ってloadHTML()メソッドのエラーを抑制していますが、これはデバッグを困難にするため、実際の開発では適切なエラーハンドリングを実装し、利用を避けてください。DOMDocument::childNodesプロパティは、ドキュメントの最も直接の子ノード(通常はDOCTYPE宣言や<html>要素など)のみを返します。ドキュメント内のより深い階層にある<body>タグ内の要素などを取得するには、<html>要素の子ノードをさらに辿るか、XPathのような強力なクエリ機能を利用する必要があります。DOMNodeListは、動的なリストであり、参照しているDOMツリーが変更されると内容も更新される点にご留意ください。