Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】DOMEntityReference::nextSiblingプロパティの使い方

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

作成日: 更新日:

基本的な使い方

『nextSiblingプロパティは、現在のDOMEntityReferenceノードの直後に存在する兄弟ノードを保持するプロパティです。DOMツリー構造において、同じ親ノードを持つノード群の中で、現在のノードのすぐ次に位置するノードが「次の兄弟ノード」となります。このプロパティを利用することで、ドキュメント内のノードを順番に処理する、いわゆる兄弟間の走査が可能になります。

もし現在のノードが、その親ノードにおける最後の子ノードである場合、直後に兄弟ノードは存在しないため、このプロパティは null を返します。この null チェックにより、兄弟ノードの終端を判定できます。取得されるノードは、要素ノード(タグ)だけでなく、テキストノード、コメントノード、あるいは改行やインデントによる空白文字のみを含むテキストノードなど、あらゆる種類のノードである可能性がある点に注意が必要です。

このプロパティは読み取り専用であり、直接値を代入してDOMツリーの構造を書き換えることはできません。ノードの挿入や移動といった操作には、DOMNode::insertBefore() などの専用メソッドを使用する必要があります。

構文(syntax)

1<?php
2
3$xml = <<<XML
4<!DOCTYPE root [
5    <!ENTITY my_entity "some text">
6]>
7<root><item1/>&my_entity;<item2/></root>
8XML;
9
10$doc = new DOMDocument();
11
12// Set to false to prevent entity substitution and create DOMEntityReference nodes
13$doc->substituteEntities = false;
14
15$doc->loadXML($xml);
16
17// Get the root element's child nodes
18$childNodes = $doc->documentElement->childNodes;
19
20// Find the DOMEntityReference node (&my_entity;)
21$entityRefNode = null;
22foreach ($childNodes as $node) {
23    if ($node->nodeType === XML_ENTITY_REF_NODE) {
24        $entityRefNode = $node;
25        break;
26    }
27}
28
29// Access the node immediately following the entity reference node
30// The property returns a ?DOMNode (DOMNode or null)
31$siblingNode = $entityRefNode->nextSibling;
32
33if ($siblingNode) {
34    // Outputs the node name of the next sibling, which is "item2"
35    echo $siblingNode->nodeName;
36}
37
38?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

DOMNode|null

このプロパティは、現在のDOMエンティティ参照ノードの次に位置する兄弟ノード、または兄弟ノードが存在しない場合はnullを返します。

サンプルコード

DOMEntityReferenceのnextSiblingを取得する

1<?php
2
3/**
4 * DOMEntityReferenceのnextSiblingプロパティの使用例を示します。
5 *
6 * この関数は、DTDでエンティティが定義されたXML文字列を解析します。
7 * そして、特定のエンティティ参照ノード(&company;)を見つけ、
8 * その直後にある兄弟ノード(この場合はテキストノード)の内容を取得して出力します。
9 */
10function showNextSiblingOfEntityReference(): void
11{
12    // DTDでエンティティ'&company;'を定義したXML文字列
13    $xmlString = <<<XML
14<?xml version="1.0" encoding="UTF-8"?>
15<!DOCTYPE document [
16    <!ENTITY company "Example Corp.">
17]>
18<document>
19    <copyright>Copyright &company; 2023. All rights reserved.</copyright>
20</document>
21XML;
22
23    // DOMDocumentオブジェクトをインスタンス化
24    $dom = new DOMDocument();
25
26    // XML文字列を読み込みます。
27    // デフォルトのオプションでは、エンティティ参照はDOMEntityReferenceノードとして扱われます。
28    $dom->loadXML($xmlString);
29
30    // <copyright>要素を取得
31    $copyrightElement = $dom->getElementsByTagName('copyright')->item(0);
32    if ($copyrightElement === null) {
33        echo "要素が見つかりませんでした。" . PHP_EOL;
34        return;
35    }
36
37    // <copyright>要素の子ノードをループしてDOMEntityReferenceを探す
38    foreach ($copyrightElement->childNodes as $childNode) {
39        if ($childNode instanceof DOMEntityReference) {
40            echo "エンティティ参照ノードが見つかりました: &" . $childNode->nodeName . ";" . PHP_EOL;
41
42            // nextSiblingプロパティで次の兄弟ノードを取得
43            $nextSiblingNode = $childNode->nextSibling;
44
45            // 次の兄弟ノードが存在するか確認
46            if ($nextSiblingNode !== null) {
47                // 次のノードはテキストノード " 2023. All rights reserved."
48                echo "次の兄弟ノードの型: " . get_class($nextSiblingNode) . PHP_EOL;
49                echo "次の兄弟ノードの値: '" . trim($nextSiblingNode->nodeValue) . "'" . PHP_EOL;
50            } else {
51                echo "次の兄弟ノードはありません。" . PHP_EOL;
52            }
53            // 目的のノードを見つけたらループを終了
54            break;
55        }
56    }
57}
58
59// 関数を実行
60showNextSiblingOfEntityReference();
61
62?>

このサンプルコードは、PHPのDOMEntityReferenceクラスが持つnextSiblingプロパティの使用方法を示しています。nextSiblingは、XML文書内のあるエンティティ参照ノードを基準として、その直後にある同じ階層のノード(兄弟ノード)を取得するためのプロパティです。引数は必要ありません。戻り値は、次の兄弟ノードが存在すればそのノードを表すDOMNodeオブジェクト、存在しなければnullとなります。

コードでは、まずDTD(文書型定義)でエンティティ&company;を定義したXML文字列をDOMDocumentオブジェクトとして読み込みます。次に、<copyright>要素の子ノードを一つずつ調べ、目的のエンティティ参照ノード(&company;)を見つけ出します。そして、そのノードに対してnextSiblingプロパティを使用し、直後にあるテキストノード「 2023. All rights reserved.」を取得しています。最後に、取得したノードの型がDOMTextであることと、その内容を画面に出力することで、プロパティが正しく機能していることを確認しています。

nextSiblingプロパティは、次の兄弟ノードが存在しない場合にnullを返します。そのため、プロパティの値を取得した後は、必ずnullでないことを確認してから使用してください。確認を怠ると、nullに対して操作しようとしてエラーが発生する原因になります。また、取得できるノードは要素だけでなく、改行やスペースを含むテキストノードの場合もあります。get_class()関数やnodeTypeプロパティで、取得したノードが意図した型であるかを確認することが大切です。このプロパティの挙動はXMLの読み込みオプションにも依存します。例えば、エンティティを展開するオプションを指定すると、サンプルコードのようには動作しなくなる点にも注意が必要です。

関連コンテンツ

関連プログラミング言語