【PHP8.x】childNodesプロパティの使い方

childNodesプロパティの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

childNodesプロパティはDom\XMLDocumentクラスにおいて、XMLドキュメントの直下にある全ての子ノードのリストを保持するプロパティです。Dom\XMLDocumentは、PHPにおいてXMLドキュメント全体をオブジェクトとして表現し、プログラムからその内容を操作するための基盤となるクラスです。

このchildNodesプロパティにアクセスすると、XMLドキュメントの最上位レベルに存在する子ノード群が、Dom\NodeListオブジェクトとして取得されます。ここでいう「子ノード」とは、XMLドキュメントを構成する個々の部品のことで、具体的にはXML宣言の後に続くルート要素、コメント、処理命令などが含まれます。

Dom\NodeListは、取得した子ノードを順序付けてリスト形式で格納しており、これを利用することで、foreachループなどを用いて個々の子ノードに簡単にアクセスし、それぞれのノードのタイプや値、属性といった情報を取得したり、さらにその子ノードを探索したりすることが可能になります。このリストはドキュメントの内容に同期しており、元のXMLドキュメントが変更されると、その変更が自動的にリストにも反映される特性を持っています。

childNodesプロパティは、XMLドキュメントの構造を上から順に探索したり、特定の要素や情報を見つけ出したり、あるいはドキュメントの特定の部分を操作したりする際に、非常に重要な役割を果たすプロパティです。XMLデータをプログラムで扱う上で、ドキュメントの全体像を把握し、必要な部分へアプローチするための入り口として利用されます。

構文(syntax)

1<?php
2
3// Dom\XMLDocument オブジェクトを作成し、XMLをロード
4$document = new Dom\XMLDocument();
5$document->loadXML('<root><item id="1">First item</item><item id="2">Second item</item></root>');
6
7// Dom\XMLDocument オブジェクトの childNodes プロパティにアクセスし、子ノードのリストを取得する構文
8$children = $document->childNodes;

引数(parameters)

引数なし

引数はありません

戻り値(return)

Dom\NodeList

Dom\XMLDocument オブジェクトの直下にある子ノードのコレクションを Dom\NodeList オブジェクトとして取得します。

サンプルコード

PHP DOM childNodes プロパティで子ノードを取得する

1<?php
2
3/**
4 * Dom\XMLDocumentのchildNodesプロパティの使用例を示します。
5 *
6 * childNodesは、指定したノードの直下にあるすべての子ノードのリストを
7 * Dom\NodeListとして返します。これには要素ノードだけでなく、
8 * コメントやテキストノードなども含まれる点に注意が必要です。
9 */
10function demonstrateChildNodesProperty(): void
11{
12    // 1. 操作対象のシンプルなXML文字列を定義します。
13    // このXMLは、ドキュメント直下にコメントノードとルート要素(<items>)を持っています。
14    $xmlString = <<<XML
15<?xml version="1.0" encoding="UTF-8"?>
16<!-- 商品リストのコメントノード -->
17<items>
18    <item id="001">リンゴ</item>
19    <item id="002">ミカン</item>
20</items>
21XML;
22
23    // 2. Dom\XMLDocumentオブジェクトを作成します。
24    // PHP 8以降、名前空間 `Dom` を使用することが推奨されます。
25    $doc = new \Dom\XMLDocument();
26
27    // 3. XML文字列を読み込み、DOMツリーを構築します。
28    $doc->loadXML($xmlString);
29
30    // 4. XMLドキュメントオブジェクトのchildNodesプロパティにアクセスします。
31    // これにより、ドキュメント直下の子ノードのリストが取得できます。
32    // この例では「コメントノード」と「<items>要素ノード」が対象となります。
33    $childNodes = $doc->childNodes;
34
35    echo "ドキュメント直下の子ノード (全" . $childNodes->length . "個):\n";
36    echo "----------------------------------------\n";
37
38    // 5. 取得したNodeListをループで処理し、各ノードの情報を出力します。
39    foreach ($childNodes as $index => $node) {
40        // nodeNameプロパティはノードの名前です。
41        // (例: コメントは'#comment'、要素はタグ名'items')
42        echo "[$index] ノード名: " . $node->nodeName . "\n";
43
44        // nodeTypeプロパティでノードの種類を判別します。
45        $nodeTypeString = match ($node->nodeType) {
46            XML_ELEMENT_NODE => '要素ノード',
47            XML_COMMENT_NODE => 'コメントノード',
48            XML_TEXT_NODE    => 'テキストノード',
49            default          => 'その他のノード',
50        };
51        echo "[$index] ノード種類: " . $nodeTypeString . "\n";
52
53        // nodeValueはノードの種類によって内容が異なります。
54        // コメントノードの場合はコメント本文、要素ノードの場合はnullになります。
55        if ($node->nodeValue !== null) {
56            echo "[$index] ノード値: " . trim($node->nodeValue) . "\n";
57        }
58        echo "----------------------------------------\n";
59    }
60}
61
62// 関数を実行して結果を表示します。
63demonstrateChildNodesProperty();

PHP 8のDom\XMLDocumentクラスのchildNodesプロパティは、特定のXMLノードの直下にあるすべての子ノードをDom\NodeListオブジェクトとして取得するために利用されます。このプロパティには引数を渡す必要がなく、戻り値としてDom\NodeListのインスタンスが返されます。このNodeListには、XMLの要素ノードだけでなく、コメントノードやテキストノードなども含まれる点が重要な特徴です。

サンプルコードでは、まずシンプルなXML文字列を定義し、それをDom\XMLDocumentオブジェクトに読み込むことで、DOMツリーを構築します。その後、$doc->childNodesという形でプロパティにアクセスすることで、XMLドキュメント直下の子ノード群(この例ではXML宣言直後のコメントノードと、<items>というルート要素ノード)をDom\NodeListとして取得しています。取得したNodeListは複数のノードのリストであり、foreach文を使用してリスト内の個々のノードを順番に処理することができます。ループ内では、各ノードのnodeName(ノードの名前、例: '#comment'やタグ名)、nodeType(ノードの種類を示す定数、例: XML_COMMENT_NODE)、nodeValue(ノードの種類に応じた値、コメント本文など)といったプロパティを出力しています。これにより、XMLドキュメントの階層構造をプログラムで効率的に探索し、特定の子ノードの情報を取得・操作する基盤を学ぶことができます。

childNodesは、要素だけでなくコメントやテキストノードも含む全ての子ノードをDom\NodeListとして返す点に注意が必要です。NodeListは配列のように扱えますが、実際の配列とは異なります。lengthプロパティで子ノードの数を取得できます。ノードの種類はnodeTypeプロパティで確認し、XML_ELEMENT_NODEXML_COMMENT_NODEなどの定数と比較します。nodeValueはノードの種類によって意味が異なり、要素ノードではnullになることがあります。XMLを扱う際は、文字コードの問題にも注意してください。

PHP DOMDocumentのchildNodesで子ノードを取得する

1<?php
2
3// XMLDocument をロードする
4$dom = new DOMDocument();
5$dom->loadXML('<root><item>Item 1</item><item>Item 2</item></root>');
6
7// XPath を使用してノードを選択する (例: root ノード)
8$xpath = new DOMXPath($dom);
9$rootNodes = $xpath->query('/root');
10
11// root ノードが存在する場合
12if ($rootNodes->length > 0) {
13    $root = $rootNodes->item(0); // 最初の root ノードを取得
14
15    // childNodes プロパティを使用して子ノードのリストを取得する
16    $childNodes = $root->childNodes;
17
18    // 子ノードを反復処理する
19    foreach ($childNodes as $childNode) {
20        // 要素ノードであるかどうかを確認する
21        if ($childNode->nodeType == XML_ELEMENT_NODE) {
22            // ノード名を出力する
23            echo "Node Name: " . $childNode->nodeName . "\n";
24
25            // テキストコンテンツを出力する (存在する場合)
26            if ($childNode->hasChildNodes()) {
27                echo "Node Value: " . $childNode->textContent . "\n";
28            }
29        }
30    }
31} else {
32    echo "Root node not found.\n";
33}
34
35?>

このサンプルコードは、PHPのDOM拡張を用いてXMLドキュメントを操作し、childNodesプロパティを使ってXMLノードの子ノードを取得する方法を示しています。

まず、DOMDocumentクラスのインスタンスを作成し、loadXMLメソッドでXML文字列を読み込みます。次に、DOMXPathクラスを使用してXPathクエリを実行し、特定のノード(この例ではルートノード)を選択します。

childNodesプロパティは、Dom\XMLDocumentクラスに所属し、ノードの子ノードをDom\NodeListオブジェクトとして返します。引数はなく、子ノードのリストを直接取得できます。

取得したDom\NodeListオブジェクトをforeachループで反復処理し、各子ノードの情報を出力します。ここでは、nodeTypeプロパティで要素ノードであるかどうかを確認し、nodeNameプロパティでノード名、textContentプロパティでノードのテキストコンテンツを取得しています。hasChildNodesメソッドを使って、子ノードがテキストコンテンツを持つか確認しています。

このコードは、XMLドキュメントの構造をプログラムで解析し、必要な情報を抽出する基本的な方法を理解するのに役立ちます。特に、childNodesプロパティは、XMLドキュメントのツリー構造を辿る上で重要な役割を果たします。

childNodesプロパティは、指定したノードの直下の子ノードをDOMNodeListとして返します。このリストには要素ノードだけでなく、テキストノードやコメントノードなども含まれる点に注意が必要です。そのため、nodeTypeプロパティでノードの種類を確認し、必要なノードのみを処理するようにしてください。また、hasChildNodes()で子ノードの有無を確認してからtextContentプロパティにアクセスすることで、エラーを回避できます。XPathでノードを選択した後、item(0)で確実に最初のノードを取得していることを確認しましょう。XMLの構造によっては、期待したノードが選択されない場合があります。

【PHP8.x】childNodesプロパティの使い方 | いっしー@Webエンジニア