【PHP8.x】DOMNotation::childNodesプロパティの使い方
childNodesプロパティの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
childNodesプロパティは、DOMツリー内のノードの子ノードをリストとして保持するプロパティです。このプロパティは、XMLドキュメントの構造をプログラムで操作するためのPHPのDOM拡張機能の一部として提供されます。
DOMNotationクラスは、XMLドキュメント型定義(DTD)内で宣言される「記法(notation)」を表すものです。記法は、XMLの外部にある非XML形式のデータを識別するために使われ、例えばMIMEタイプなどを指定する際に利用されます。
一般的なDOMノードにおいて、childNodesプロパティは、そのノードが直接持つすべての子ノードの集合をDOMNodeListオブジェクトとして返します。しかし、DOM仕様では、DOMNotationノードは子ノードを持つことができない特殊なノードタイプと定められています。
したがって、DOMNotationオブジェクトのchildNodesプロパティにアクセスした場合、返されるDOMNodeListオブジェクトは常に空となり、いかなる子ノードも含まれません。これは、DOMNotationノードがそれ自体で完結しており、内部に他の構造を持つことを意図されていないためです。このプロパティは読み取り専用であり、子ノードを追加したり削除したりすることはできません。
構文(syntax)
1<?php 2$xmlString = '<!DOCTYPE root [<!NOTATION gif SYSTEM "image/gif">]><root/>'; 3$dom = new DOMDocument(); 4$dom->loadXML($xmlString); 5 6// ドキュメントタイプから最初のNOTATIONノードを取得します。 7$notation = $dom->doctype->notations->item(0); 8 9// DOMNotationオブジェクトのchildNodesプロパティにアクセスします。 10// DOMNotationノードは子ノードを持たないため、これは常に空のDOMNodeListを返します。 11$childNodes = $notation->childNodes; 12 13// 取得したDOMNodeListの要素数を表示します。 14echo "DOMNotation childNodes length: " . $childNodes->length; 15?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
DOMNodeList
DOMNotation オブジェクトの子ノードのリストを DOMNodeList オブジェクトとして返します。
サンプルコード
PHP DOM NotationのchildNodesを調べる
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOMNotationのchildNodesプロパティの使用例を示します。 7 * 8 * DOMNotationノードは、DTD(文書型定義)で定義される「記法」を表します。 9 * このノードは構造上、子ノードを持つことができません。 10 * このサンプルでは、childNodesプロパティが常に空のDOMNodeListを返すことを確認します。 11 */ 12function showDomNotationChildNodes(): void 13{ 14 // DTD内で記法(Notation) 'jpeg' を定義したXML文字列 15 $xmlString = <<<XML 16 <?xml version="1.0" encoding="UTF-8"?> 17 <!DOCTYPE root [ 18 <!NOTATION jpeg SYSTEM "image/jpeg"> 19 <!ELEMENT root EMPTY> 20 ]> 21 <root/> 22 XML; 23 24 // DOMDocumentオブジェクトを生成 25 $dom = new DOMDocument(); 26 27 // DTDを読み込むオプションを付けてXMLをロードします。 28 // このオプションがないと、DTD内の情報は解析されません。 29 $dom->loadXML($xmlString, LIBXML_DTDLOAD); 30 31 // DocumentTypeノードから記法のリスト(DOMNamedNodeMap)を取得 32 $notations = $dom->doctype->notations; 33 34 // 'jpeg' という名前の記法 (DOMNotationオブジェクト) を取得 35 $jpegNotation = $notations->getNamedItem('jpeg'); 36 37 if ($jpegNotation instanceof DOMNotation) { 38 // DOMNotationオブジェクトのchildNodesプロパティにアクセスします。 39 // このプロパティは子ノードのリスト(DOMNodeList)を返します。 40 $childNodes = $jpegNotation->childNodes; 41 42 // 記法ノードは子ノードを持てないため、リストの長さ(length)は常に0です。 43 echo "子ノードの数: " . $childNodes->length . PHP_EOL; 44 45 // childNodesプロパティの戻り値の型を確認します。 46 echo "戻り値の型: " . get_class($childNodes) . PHP_EOL; 47 } else { 48 echo "指定された記法が見つかりませんでした。"; 49 } 50} 51 52// 関数を実行して結果を表示 53showDomNotationChildNodes(); 54 55?>
DOMNotationクラスのchildNodesプロパティは、記法(Notation)ノードが持つすべての子ノードのリストを取得するために使用されます。このプロパティは引数を取りません。
戻り値は、子ノードの集合であるDOMNodeListオブジェクトです。しかし、XMLの仕様上、記法ノードは子要素やテキストなどを持つことができません。そのため、childNodesプロパティは常に空のDOMNodeListを返します。つまり、リストに含まれるノードの数は常に0になります。
サンプルコードでは、まずDTD(文書型定義)でjpegという記法を定義したXML文書を読み込みます。次に、このjpeg記法を表すDOMNotationオブジェクトを取得し、そのchildNodesプロパティにアクセスしています。プロパティが返すDOMNodeListオブジェクトのlengthプロパティ(リスト内のノード数)を出力することで、子ノードの数が0であることを確認できます。このコードは、DOMNotationノードが構造的に子を持たないという仕様を実際に示しています。
DOMNotationは、DTDで定義される「記法」を表す特殊なノードであり、XMLの構造上、子ノードを持つことができません。そのため、childNodesプロパティは常に空のDOMNodeListオブジェクトを返します。このプロパティのlengthは常に0であり、子ノードの繰り返し処理などに利用しようとしても、何も実行されない点に注意が必要です。また、サンプルコードのようにDTD内の記法情報を扱うには、loadXMLメソッドの第二引数にLIBXML_DTDLOADオプションを指定することが不可欠です。このオプションがないとDTDが解析されず、記法ノードを取得できません。getNamedItemは対象が見つからないとnullを返すため、プロパティにアクセスする前にinstanceofで型を確認することは安全なコードにつながります。