【PHP8.x】childNodesプロパティの使い方
childNodesプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『childNodesプロパティは、あるノードの直接の子である全ての子ノードの集合を、Dom\NodeListオブジェクトとして保持するプロパティです。このプロパティは読み取り専用であり、DOMツリーの構造を調べる際に使用されます。返されるDom\NodeListは、子ノードの順序付きコレクションであり、配列のようにインデックス番号を用いて各子ノードにアクセスできます。子ノードには、HTMLタグなどの要素ノードだけでなく、テキスト、コメント、処理命令など、あらゆる種類のノードが含まれる点に注意が必要です。例えば、要素間の改行やインデントに使われる空白文字もテキストノードとして扱われることがあります。また、childNodesが返すNodeListは「ライブ」な状態です。これは、元のDOMツリーに対してappendChildメソッドなどで子ノードが追加または削除されると、その変更がNodeListオブジェクトにも自動的に反映されることを意味します。もし対象のノードに子ノードが一つも存在しない場合は、空のDom\NodeListが返されます。
構文(syntax)
1<?php 2$dom = new DOMDocument(); 3$dom->loadHTML('<html><body><p>段落1</p>テキストノード<!-- コメント --></div></body></html>', LIBXML_NOEMPTYTAG); 4 5// body要素 (Dom\Node) を取得します 6$body = $dom->getElementsByTagName('body')->item(0); 7 8// body要素のすべての子ノード (Dom\NodeList) を取得します 9$childNodes = $body->childNodes; 10 11// すべての子ノードをループ処理して、そのノード名を出力します 12foreach ($childNodes as $node) { 13 // $nodeはDom\Nodeオブジェクトです 14 echo $node->nodeName . PHP_EOL; 15} 16?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
?Dom\NodeList
Dom\Nodeオブジェクトの子ノードのコレクションをDom\NodeListオブジェクトとして返します。子ノードが存在しない場合はnullを返します。
サンプルコード
PHP 8 Dom childNodesで子ノードを取得する
1<?php 2 3/** 4 * Demonstrates the use of the Dom\Node::childNodes property in PHP 8. 5 * 6 * This function parses a simple HTML string, identifies a specific parent element, 7 * and then iterates through its direct child nodes using the `childNodes` property. 8 * It shows how to access different types of nodes (element, text, comment) that 9 * can be returned by this property. 10 */ 11function demonstrateDomChildNodes(): void 12{ 13 // 1. Create a new Dom\Document instance. 14 $document = new Dom\Document(); 15 16 // 2. Load a simple HTML string into the document. 17 // The whitespace between elements (like newline characters) will also be treated as text nodes. 18 $html = <<<HTML 19<!DOCTYPE html> 20<html> 21<head> 22 <title>ChildNodes Example</title> 23</head> 24<body> 25 <div id="main-container"> 26 <!-- This is a comment inside the container --> 27 <p>This is the first paragraph child.</p> 28 Some direct text content. 29 <span>This is a span element child.</span> 30 </div> 31</body> 32</html> 33HTML; 34 $document->loadHTML($html); 35 36 // 3. Find the parent node whose children we want to examine. 37 // We'll get the div element with id="main-container". 38 $containerNode = $document->getElementById('main-container'); 39 40 if ($containerNode === null) { 41 echo "Error: Could not find the '#main-container' element.\n"; 42 return; 43 } 44 45 echo "--- Examining childNodes of the '{$containerNode->nodeName}' element (ID: {$containerNode->getAttribute('id')}) ---\n\n"; 46 47 // 4. Access the `childNodes` property. 48 // This property returns a `Dom\NodeList` containing all direct children of the node, 49 // including element nodes, text nodes, and comment nodes. 50 // The return type is `?Dom\NodeList`, meaning it could theoretically be null, 51 // but for an existing node, it typically returns an empty `Dom\NodeList` if there are no children. 52 $childNodes = $containerNode->childNodes; 53 54 // Check if the property returned a Dom\NodeList. 55 if ($childNodes === null) { 56 echo "The childNodes property returned null. This is unexpected for an existing node.\n"; 57 return; 58 } 59 60 // 5. Iterate through the `Dom\NodeList` and display information about each child node. 61 if ($childNodes->length > 0) { 62 echo "Found {$childNodes->length} direct child nodes:\n"; 63 foreach ($childNodes as $index => $node) { 64 // Determine the human-readable type of the node. 65 $nodeTypeName = match ($node->nodeType) { 66 XML_ELEMENT_NODE => 'ELEMENT_NODE', 67 XML_TEXT_NODE => 'TEXT_NODE', 68 XML_COMMENT_NODE => 'COMMENT_NODE', 69 XML_CDATA_SECTION_NODE => 'CDATA_SECTION_NODE', 70 XML_DOCUMENT_TYPE_NODE => 'DOCUMENT_TYPE_NODE', 71 default => 'UNKNOWN_NODE_TYPE (' . $node->nodeType . ')', 72 }; 73 74 echo " [$index] Type: {$nodeTypeName} (Code: {$node->nodeType})"; 75 echo ", Name: '{$node->nodeName}'"; 76 77 // Truncate long text values for better readability and clean up whitespace. 78 $valuePreview = str_replace(["\n", "\r"], ' ', $node->nodeValue); 79 $valuePreview = preg_replace('/\s+/', ' ', $valuePreview); // Replace multiple spaces with single space 80 $valuePreview = trim($valuePreview); 81 82 if (strlen($valuePreview) > 50) { 83 $valuePreview = substr($valuePreview, 0, 50) . '...'; 84 } 85 echo ", Value (Preview): '{$valuePreview}'\n"; 86 } 87 } else { 88 echo "No direct child nodes found for this element.\n"; 89 } 90} 91 92// Execute the demonstration function. 93demonstrateDomChildNodes(); 94 95?>
PHP 8で提供されるDom\Node::childNodesは、DOM(Document Object Model)ツリーを操作する際に、特定のノードが直接持つ全ての子ノードのリストを取得するためのプロパティです。これはDom\Nodeクラスの一部であり、HTMLやXML文書の構造をプログラムから詳細に扱う際に活用されます。
このプロパティは引数を取りません。戻り値は?Dom\NodeListで、これは取得された全ての子ノードを順序付けて格納するリスト形式のオブジェクトです。戻り値が?(Nullable)と示されているのは、理論上nullを返す可能性があるためですが、通常、既存のノードに対しては、子ノードが存在しない場合でも空のDom\NodeListオブジェクトが返されます。
サンプルコードでは、まず簡単なHTML文字列をDom\Documentに読み込み、特定のdiv要素を親ノードとして特定しています。その後、この親ノードのchildNodesプロパティにアクセスすることで、その直下にある全ての子ノード(要素ノード、テキストノード、コメントノードなど)のリストを取得しています。そして、取得したDom\NodeListをループ処理し、各子ノードのタイプ(要素、テキスト、コメントなど)や内容(nodeValue)を出力することで、DOMツリーがどのように構築され、どのような情報を含んでいるのかを具体的に理解できるようになっています。特に、要素間の改行や空白もテキストノードとして認識される点に注目してください。
Dom\Node::childNodesプロパティは、HTMLやXML文書の特定のノード直下にある全ての子ノードを取得します。初心者が特に注意すべき点は、HTMLソース中の改行やインデントといった空白もテキストノード(XML_TEXT_NODE)として含まれることです。そのため、期待する要素ノード(XML_ELEMENT_NODE)のみを扱いたい場合は、取得したノードリストをループ処理し、nodeTypeプロパティでノードの種類を判別し、明示的にフィルタリングする必要があります。
また、このプロパティは通常Dom\NodeListオブジェクトを返しますが、理論的にはnullを返す可能性もゼロではありません。安全なコードのため、取得したノードリストがnullでないか確認するチェックを行うことが推奨されます。取得したDom\NodeListは、lengthプロパティで子ノードの数を取得でき、foreach文で各子ノードに簡単にアクセスして処理できます。