【PHP8.x】Dom\Entity::appendChild()メソッドの使い方
appendChildメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『appendChildメソッドは、あるノードの子ノードリストの末尾に、新しい子ノードを追加する処理を実行するメソッドです。このメソッドは、XMLドキュメントのDTD(文書型定義)で定義されたエンティティ(実体)を表すDom\Entityクラスに属しています。しかし、DOMの仕様上、Dom\Entityノードは子ノードを持つことができません。そのため、Dom\Entityオブジェクトに対してこのメソッドを使用して子ノードを追加しようとすると、操作が許可されていないため、常にDOMExceptionという例外が発生し、処理は失敗します。引数には追加したいDom\Nodeオブジェクトを渡しますが、どのようなノードを指定してもこの結果は変わりません。通常、他のクラス(例えばDom\Element)でこのメソッドが成功裏に実行された場合は、追加されたノードが戻り値として返されますが、Dom\Entityの場合は例外がスローされるため、正常な戻り値を得ることはありません。したがって、このクラスにおいてappendChildメソッドは実質的に使用できない点に注意が必要です。』
構文(syntax)
1$appendedNode = $entity->appendChild($newNode);
引数(parameters)
Dom\Node $node
- Dom\Node $node: 追加する子ノードを指定する
Dom\Nodeオブジェクト
戻り値(return)
Dom\Node
Dom\Node オブジェクトを返します。これは、新しく追加された子ノード自身です。
サンプルコード
PHP DOM appendChildで要素を追加する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * DOMDocument を使用してHTMLドキュメントを構築し、 7 * appendChild() メソッドで要素を追加するサンプル関数です。 8 * 9 * appendChild() は、指定したノードを、呼び出し元ノードの子リストの末尾に追加します。 10 */ 11function createHtmlWithAppendChild(): void 12{ 13 // 1. DOMDocumentのインスタンスを生成します。 14 // これがHTMLドキュメント全体を操作するための基本オブジェクトになります。 15 $dom = new DOMDocument('1.0', 'UTF-8'); 16 17 // 生成されるHTMLを見やすくインデントするために設定します。 18 $dom->formatOutput = true; 19 20 // 2. HTMLの各要素(ノード)を作成します。 21 // この時点では、各要素は独立しており、親子関係はありません。 22 $htmlElement = $dom->createElement('html'); 23 $htmlElement->setAttribute('lang', 'ja'); 24 25 $bodyElement = $dom->createElement('body'); 26 $h1Element = $dom->createElement('h1', 'DOMのサンプル'); 27 $pElement = $dom->createElement('p', 'appendChild() メソッドを使って要素を追加しました。'); 28 29 // 3. appendChild() を使って親子関係を構築します。 30 // $bodyElement の子として $h1Element を追加します。 31 $bodyElement->appendChild($h1Element); 32 33 // $bodyElement の子として $pElement を追加します。 34 // h1要素の後ろに追加されます。 35 $bodyElement->appendChild($pElement); 36 37 // $htmlElement の子として、完成した $bodyElement を追加します。 38 $htmlElement->appendChild($bodyElement); 39 40 // 最後に、ドキュメントのルート要素として $htmlElement を追加します。 41 $dom->appendChild($htmlElement); 42 43 // 4. 作成したDOMオブジェクトをHTML文字列として出力します。 44 echo $dom->saveHTML(); 45} 46 47// 関数を実行して結果を表示します。 48createHtmlWithAppendChild();
Dom\EntityクラスのappendChild()メソッドは、指定したノードを、呼び出し元ノードの子リストの末尾に追加します。プログラムによって動的にHTMLなどの階層構造を組み立てる際に非常に重要な役割を果たします。
サンプルコードでは、まずDOMDocumentオブジェクトと、createElement()メソッドを使ってhtmlやbodyなどの個別のHTML要素(ノード)を作成しています。この時点では各要素は独立しており、互いに関連付けられていません。
次にappendChild()メソッドを用いて、これらの独立した要素に親子関係を設定し、階層構造を構築していきます。具体的には、body要素の子としてh1要素とp要素を順番に追加し、次にhtml要素の子としてそのbody要素を追加しています。最後に、ドキュメント全体のルート要素としてhtml要素を追加することで、一つの完成したHTMLドキュメントを構成しています。
このメソッドの引数には、子として追加したいDom\Nodeオブジェクトを指定します。処理が成功すると、戻り値として追加されたそのノード自身が返されます。
appendChildメソッドは、指定した要素を子要素リストの末尾に追加します。そのため、同じ親要素に対して複数回呼び出すと、呼び出した順番で要素が並びます。注意点として、追加しようとする要素が既にドキュメント内の別の場所に存在する場合、元の場所からは自動的に削除され、新しい場所へ移動します。つまり、一つの要素が同時に複数の親を持つことはできません。また、追加する要素は、必ず追加先の親要素と同じDOMDocumentインスタンスによって作成されている必要があります。異なるインスタンスで作成した要素を追加しようとするとエラーが発生するため、安全に利用するにはこの点を意識することが重要です。
PHP SimpleXMLで子要素を追加する
1<?php 2 3declare(strict_types=1); 4 5/** 6 * SimpleXMLを使用してXMLドキュメントに子要素を追加するサンプル 7 * 8 * SimpleXMLElementにはappendChildという名前のメソッドはありませんが、 9 * 同様の機能を持つaddChildメソッドを使用して子要素を追加できます。 10 * 11 * @return void 12 */ 13function addXmlElement(): void 14{ 15 // 1. ベースとなるXML文字列を定義 16 $xmlString = <<<XML 17<?xml version="1.0" encoding="UTF-8"?> 18<bookstore> 19 <book category="COOKING"> 20 <title lang="en">Everyday Italian</title> 21 <author>Giada De Laurentiis</author> 22 <year>2005</year> 23 <price>30.00</price> 24 </book> 25</bookstore> 26XML; 27 28 // 2. XML文字列をSimpleXMLElementオブジェクトに読み込む 29 try { 30 $xml = new SimpleXMLElement($xmlString); 31 } catch (Exception $e) { 32 // XMLのパースに失敗した場合の処理 33 header('Content-Type: text/plain; charset=utf-8'); 34 echo "XMLの解析に失敗しました: " . $e->getMessage(); 35 return; 36 } 37 38 // 3. 新しい <book> 要素をルート要素(<bookstore>)の子として追加する 39 // addChild() は追加された新しい要素のSimpleXMLElementを返す 40 $newBook = $xml->addChild('book'); 41 42 // 4. 新しく追加した<book>要素に属性を追加する 43 $newBook->addAttribute('category', 'WEB'); 44 45 // 5. <book>要素にさらに子要素(<title>, <author>, <year>, <price>)を追加する 46 // addChild()の第2引数で要素のテキストコンテンツを指定できる 47 $newBook->addChild('title', 'Learning PHP')->addAttribute('lang', 'en'); 48 $newBook->addChild('author', 'John Doe'); 49 $newBook->addChild('year', '2023'); 50 $newBook->addChild('price', '45.50'); 51 52 // 6. 変更後のXMLを整形して出力するためにDOMDocumentを利用する 53 $dom = new DOMDocument('1.0', 'UTF-8'); 54 $dom->preserveWhiteSpace = false; 55 $dom->formatOutput = true; 56 // SimpleXMLElementをDOMElementにインポート 57 $dom->loadXML($xml->asXML()); 58 59 // HTTPヘッダーを設定して、ブラウザがXMLとして解釈するようにする 60 header('Content-Type: application/xml; charset=utf-8'); 61 62 // 整形されたXMLを出力 63 echo $dom->saveXML(); 64} 65 66// 関数を実行 67addXmlElement();
このPHPサンプルコードは、SimpleXML拡張機能を用いて、既存のXMLデータに新しい子要素を追加する方法を示しています。キーワードとしてappendChildが挙げられていますが、これはPHPのDOM拡張で使われるメソッド名です。SimpleXML拡張では、同様の機能を提供するaddChild()メソッドを使用します。
コードの流れとして、まずXML形式の文字列をSimpleXMLElementオブジェクトとして読み込みます。次に、XMLのルート要素(この例では<bookstore>)に対してaddChild()メソッドを呼び出し、新しい<book>要素を追加します。addChild()の第一引数には、追加したい要素の名前を文字列で指定します。このメソッドは、追加された新しい要素自身をSimpleXMLElementオブジェクトとして返すため、その戻り値を変数に格納し、続けて属性やさらに内側の要素を追加していくことができます。
サンプルでは、新しく追加した<book>要素に対してaddAttribute()で属性を、さらにaddChild()で<title>や<author>といった子要素を設定しています。addChild()の第二引数に値を指定すると、それが要素のテキスト内容になります。最後に、完成したXMLデータをDOMDocumentを使って整形し、ブラウザで正しく表示されるように出力しています。
このコードは、SimpleXMLでXML要素を追加する方法を示しています。DOM拡張機能のappendChildメソッドはSimpleXMLには存在せず、代わりにaddChildメソッドを使用する点が重要です。addChildは、第1引数に要素名、第2引数にテキスト内容を指定できます。要素を追加した後、addAttributeで属性を付与します。また、不正なXML文字列を読み込むと例外が発生するため、try-catchでエラー処理をすることが安全なコードの基本です。最後に、生成したXMLを整形して出力するためにDOMDocumentを利用しています。SimpleXMLのasXML()だけでは一行で出力されるため、この方法は可読性を高めるのに有効です。