PHPで外部システムとの連携や設定ファイルの読み込みを行う際、避けて通れないのがXMLの操作です。単純な読み込みであればSimpleXMLも便利ですが、複雑な構造を持つXMLや、特定条件下でのノード検索・編集が必要な場合、DOMDocumentとXPathを組み合わせる手法が実務において非常に強力です。
今回は、PHPでXMLを扱う際の標準的かつ効率的なアプローチについて解説します。
DOMDocumentの基礎知識
DOMDocumentは、XMLドキュメントをツリー構造としてメモリ上に展開し、各ノード(要素)をオブジェクトとして操作するためのクラスです。
XMLの構造をプログラムから直接操作できるため、値の取得だけでなく、属性の更新やノードの追加・削除といった編集作業にも適しています。
実装のポイント:XPathで「検索」をスマートに
XML内の特定の要素を探す際、ループ処理で全件走査するのは非効率かつコードが冗長になりがちです。ここでXPathの出番です。XPathを利用することで、ディレクトリパスを指定するように直感的なクエリで必要なノードをピンポイントで抽出できます。
以下に、XPathを用いた実用的な検索例を示します。
サンプルプログラム:XPathによる条件検索
EOD;
$dom = new DOMDocument(‘1.0’, ‘UTF-8’);
// 不要なホワイトスペースを削除して読み込み
$dom->preserveWhiteSpace = false;
$dom->loadXML($xml);
// XPathオブジェクトの生成
$xpath = new DOMXPath($dom);
// クエリ実行:id属性が3であるsampleノードを取得
// @は属性を指定する際に使用します
$result = $xpath->query(‘//sample[@id=”3″]’)->item(0);
if ($result) {
// 値の取得
echo “取得した値: ” . $result->nodeValue . PHP_EOL;
// 値の更新(編集も簡単に行えます)
$result->nodeValue = “updated_test”;
}
// 削除の例:親ノードを取得してremoveChildを呼び出す
// ノード自身は自分を削除できないため、必ず親から操作します
$target = $xpath->query(‘/data/sample[@id=”1″]’)->item(0);
if ($target) {
$target->parentNode->removeChild($target);
}
// 編集後のXMLを確認
echo $dom->saveXML();
?>
応用・注意点:現場で陥りやすい落とし穴
1. ノード削除の鉄則:
サンプルコードでも触れましたが、ノードを削除する際は必ず $node->parentNode->removeChild($node) のように、親ノードを介して実行してください。自分自身を消そうとしてエラーになるケースは非常に多いです。
2. コンテキストノードの活用:
大きなXMLから特定のブロック内だけを再検索したい場合、query()メソッドの第2引数に親ノードを渡すのが効率的です。その際、クエリの先頭を「//」ではなく「.//」から始めることで、親ノードを起点とした相対パス検索が可能になります。
3. 文字コードの扱い:
DOMDocumentは内部的にUTF-8を前提としています。読み込むXMLがShift-JISなどの場合は、予めmb_convert_encoding等で変換するか、XML宣言を適切に処理しないと文字化けの原因になります。
XPathを使いこなすと、複雑なXML操作も非常にシンプルに記述できます。スクレイピングやAPI連携の現場で、ぜひこの手法を役立ててください。