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

【PHP8.x】DOMDocumentType::previousSiblingプロパティの使い方

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

作成日: 更新日:

基本的な使い方

『previousSiblingプロパティは、DOMツリーにおいて、現在のノードの直前に位置する兄弟ノードを保持するプロパティです。DOM(Document Object Model)では、HTMLやXML文書がツリーのような階層構造として扱われ、その構成要素は「ノード」と呼ばれます。同じ親ノードの配下にあるノード同士は「兄弟ノード」という関係になります。このpreviousSiblingプロパティにアクセスすると、現在のノードと同じ階層にあり、かつその直前に配置されているノードをDOMNodeオブジェクトとして取得できます。例えば、DOMDocumentTypeノード(文書型宣言)の直前にXML宣言やコメントノードが存在する場合、このプロパティはそのノードを返します。もし直前に兄弟となるノードが存在しない場合、このプロパティの値はnullとなります。したがって、このプロパティを利用する際は、取得した値がnullでないことを確認してから処理を行うことが重要です。このプロパティは読み取り専用であり、文書の構造を前方、つまり文書の先頭方向へたどる際に役立ちます。』

構文(syntax)

1<?php
2
3$xmlString = <<<XML
4<?xml version="1.0" encoding="UTF-8"?>
5<!-- これは前の兄弟ノード(コメント)です -->
6<!DOCTYPE root>
7<root />
8XML;
9
10$doc = new DOMDocument();
11$doc->loadXML($xmlString);
12
13// DOMDocumentTypeノード(<!DOCTYPE root>)を取得します
14$doctype = $doc->doctype;
15
16// previousSiblingプロパティで、直前の兄弟ノードを取得します
17$previousNode = $doctype->previousSibling;
18
19// 取得したノード(この場合はコメントノード)のテキスト内容を出力します
20var_dump($previousNode->nodeValue);
21
22?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

DOMNode|null

DOMDocumentType オブジェクトが持つ、このノードの直前の兄弟ノードを表す DOMNode オブジェクト、または兄弟ノードが存在しない場合は null を返します。

サンプルコード

DOMDocumentTypeの前の兄弟ノードを取得する

1<?php
2
3/**
4 * Demonstrates how to access the previousSibling of a DOMDocumentType node.
5 *
6 * This function creates an XML document with a specific structure that ensures
7 * the DOMDocumentType node has a preceding sibling (a comment node in this case).
8 * It illustrates how to navigate DOM nodes using the previousSibling property,
9 * which is useful for system engineers working with XML/HTML parsing.
10 */
11function demonstrateDomDocumentTypePreviousSibling(): void
12{
13    // 1. Create an XML string.
14    // This string includes a processing instruction and a comment *before* the DOCTYPE.
15    // This setup allows the DOMDocumentType node to have a non-null previousSibling.
16    $xmlString = <<<'XML'
17<?xml version="1.0" encoding="UTF-8"?>
18<!-- This is a comment node before the DOCTYPE -->
19<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
20<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
21    <body>
22        <p>A simple paragraph.</p>
23    </body>
24</html>
25XML;
26
27    // 2. Create a new DOMDocument instance.
28    $dom = new DOMDocument();
29
30    // 3. Load the XML string into the DOMDocument.
31    // `libxml_use_internal_errors(true)` is often used to suppress warnings
32    // for malformed XML, allowing custom error handling if needed.
33    libxml_use_internal_errors(true);
34    $dom->loadXML($xmlString);
35    libxml_clear_errors(); // Clear any potential parsing errors.
36
37    // 4. Get the DOMDocumentType node from the document.
38    // The `doctype` property holds the document type declaration.
39    $doctypeNode = $dom->doctype;
40
41    if ($doctypeNode instanceof DOMDocumentType) {
42        echo "Found DOCTYPE node with name: " . $doctypeNode->nodeName . "\n";
43        echo "Node value (publicId): " . $doctypeNode->publicId . "\n";
44
45        // 5. Access the immediately preceding sibling node of the DOCTYPE.
46        $previousSibling = $doctypeNode->previousSibling;
47
48        // 6. Check if a previous sibling exists and display its details.
49        if ($previousSibling instanceof DOMNode) {
50            echo "\nPrevious sibling found for DOCTYPE:\n";
51            echo "  Type: " . get_class($previousSibling) . "\n";
52            echo "  Node Name: " . $previousSibling->nodeName . "\n";
53            // For a comment node, nodeType is DOM_COMMENT_NODE (8)
54            // For a processing instruction, nodeType is DOM_PROCESSING_INSTRUCTION_NODE (7)
55            echo "  Node Type (numeric): " . $previousSibling->nodeType . "\n";
56            echo "  Node Value (trimmed): " . trim($previousSibling->nodeValue) . "\n";
57        } else {
58            // This path would be taken if the DOCTYPE was the very first node
59            // in the document (e.g., no XML declaration or comments before it).
60            echo "\nNo previous sibling found for the DOCTYPE node.\n";
61        }
62    } else {
63        echo "No DOCTYPE node found in the document.\n";
64    }
65}
66
67// Execute the demonstration function.
68demonstrateDomDocumentTypePreviousSibling();

PHPのDOMDocumentType::previousSiblingプロパティは、XMLやHTMLドキュメント内で、DOCTYPE宣言ノードの直前にある兄弟ノードを取得する際に利用されます。このプロパティは引数を取らず、戻り値として、直前の兄弟ノードがDOMNodeオブジェクトとして存在すればそれを返し、存在しない場合はnullを返します。

提示されたサンプルコードでは、DOCTYPE宣言の直前にコメントノードを含むXML文字列を準備し、それをDOMDocumentインスタンスに読み込んでいます。この準備により、DOCTYPEノードが確実に直前の兄弟ノードを持つ状態を作り出しています。

コードは、$dom->doctypeプロパティからDOMDocumentTypeノードを取得した後、その$doctypeNode->previousSiblingにアクセスしています。この処理により、今回のXML構造ではDOCTYPEノードの直前にあるコメントノードがDOMNodeとして取得されます。もしDOCTYPEノードがドキュメントの最も最初のノードであり、その前に何も存在しない場合は、previousSiblingnullを返します。

このプロパティは、XMLやHTMLのDOMツリーを走査し、特定のノードの前にある要素やコメント、処理命令といった他のノードをプログラムから確認・操作する際に、システムエンジニアにとって非常に有用な機能となります。

DOMDocumentType::previousSiblingは、その名の通り直前の兄弟ノードを返しますが、常にノードが存在するとは限らず、ドキュメントの先頭にある場合などはnullを返します。そのため、サンプルコードのようにif ($previousSibling instanceof DOMNode)nullでないか必ずチェックすることが重要です。返されるノードの種類は、XML宣言、コメント、処理命令など様々です。ノードの種類によってnodeNamenodeValueが示す内容が異なるため、これらのプロパティにアクセスする際は、どのようなノードが返されるかを把握しておく必要があります。特にXMLファイルの構造によっては、予期せぬノードが兄弟として存在する可能性もありますので注意しましょう。

DOMDocumentType::previousSibling を確認する

1<?php
2
3// DOMDocument オブジェクトを作成します。
4$dom = new DOMDocument();
5
6// <!DOCTYPE html> 宣言を含むシンプルな HTML をロードします。
7// これにより、DOMDocumentType ノードがパースされ、DOMツリーの一部となります。
8$htmlContent = '<!DOCTYPE html><html><body><h1>Hello</h1></body></html>';
9$dom->loadHTML($htmlContent);
10
11// 文書から DOMDocumentType ノードを取得します。
12// <!DOCTYPE html> は DOMDocumentType のインスタンスとして表現されます。
13$documentTypeNode = $dom->doctype;
14
15// DOMDocumentType::previousSibling プロパティにアクセスします。
16// DOMDocumentType ノードは通常、文書の最初の子ノード(ルート要素の前)であるため、
17// その前の兄弟ノードは存在せず、このプロパティは null を返します。
18$previousNode = $documentTypeNode->previousSibling;
19
20// 取得した前の兄弟ノードの情報を出力します。
21if ($previousNode === null) {
22    echo "DOMDocumentType ノードの前の兄弟ノードは存在しません (null)。\n";
23    echo "これは、DOCTYPE 宣言が通常、文書の最初の子ノードであるためです。\n";
24} else {
25    // この部分は DOMDocumentType の場合、通常は実行されません。
26    // もし、DOCTYPE 宣言の前に別のノードが存在するような特殊なケースがあれば、
27    // そのノードの情報を表示します。
28    echo "DOMDocumentType ノードの前の兄弟ノードが見つかりました。\n";
29    echo "ノード名: " . $previousNode->nodeName . "\n";
30    echo "ノードタイプ: " . $previousNode->nodeType . "\n";
31    echo "ノード値: " . $previousNode->nodeValue . "\n";
32}
33
34?>

PHPのDOMDocumentType::previousSiblingプロパティは、HTMLやXML文書の構造(DOMツリー)において、現在注目しているノードの「直前の兄弟ノード」を取得するために使用します。このプロパティは引数を取らず、戻り値として直前の兄弟ノードがDOMNodeオブジェクトとして返されるか、兄弟ノードが存在しない場合はnullを返します。

DOMDocumentTypeクラスは、HTMLの<!DOCTYPE html>のような文書型宣言を表すノードです。サンプルコードでは、まずDOMDocumentオブジェクトにHTMLコンテンツをロードし、その中から$dom->doctypeプロパティを使ってDOMDocumentTypeノード(この場合<!DOCTYPE html>)を取得しています。

その後、$documentTypeNode->previousSiblingにアクセスしていますが、HTML文書において<!DOCTYPE html>宣言は通常、文書の冒頭に位置し、その前に他のノードは存在しません。そのため、このプロパティはnullを返します。サンプルコードでは、このnullが返されるケースをif ($previousNode === null)で確認し、その結果を出力しています。これにより、文書型宣言の前の兄弟ノードが存在しないという、一般的な挙動を理解することができます。このプロパティは、DOMツリー内でのノード間の相対的な位置関係を探索する際に役立ちます。

previousSiblingプロパティは、前の兄弟ノードが存在しない場合にnullを返します。特にDOMDocumentTypeノードは通常、文書の最初の要素であるため、その前の兄弟ノードは存在せず、このプロパティはほぼ常にnullとなります。したがって、このプロパティから取得した値は必ずnullチェックを行い、ノードが存在するかどうかを確認してから処理を進めるようにしてください。nullでなければDOMNodeオブジェクトとして扱え、ノード名やタイプなどの情報を取得できますが、本サンプルのDOMDocumentTypeの場合、そのコードパスが実行されることは通常ありません。常にnullの可能性を考慮した安全なコーディングが重要です。

関連コンテンツ

関連IT用語

関連プログラミング言語