PHP で XML を読み書きする (DOM)

ちょっとしたデータの保管や、RSS、サイトマップなどを出力する際、
XML を扱うことはかなり多いと思いますが、
実際に操作してみるとなんとなくややこしいように見えるので
基本的な方法をまとめておきます。

新規に XML を作るには、新しくDOM ドキュメントを作ります。
「1.0」は XML のバージョンで、「UTF-8」は文字コードの指定です

$dom = new DOMDocument('1.0', 'UTF-8');

ファイルから読み込む場合も新しい DOM ドキュメントを作り、
その中にファイルの内容を読み込みます。

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->load("sample.xml");

すでに変数の中に文字列として XML の内容を読み込んである場合は
loadXML() を利用します。

$string = file_get_contents("sample.xml");
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadXML($string);

このままでも読み込みとしては問題ないのですが、
保存時や出力時に改行やインデントがなくなるため、
整形された XML を出力したい時は次のようにします。

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load("sample.xml");

ノードを追加するには、createChild() でノードを作成し、
appendChild でノードを追加するのが基本的な流れです。

$datanode = $dom->createElement("data");
$root = $dom->appendChild($datanode);

この場合は空っぽのノード <data /> が作られます。
ではこの親ノードに値を持つ子ノードを追加してみます。

$childnode = $root->appendChild($dom->createElement("child", "Hello"));

今回は省略して一行にまとめてみましたがやっていることは同じです。
実行結果は下のようなります。

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <child>Hello</child>
</data>

テキストノードの代わりに CDATASection を挿入することも出来ます。
CDATASection内部では「<>」などの記号をエスケープすることなく扱うことが出来ます。
通常のテキストノードであっても自動的に「&lt;」のように変換されるので問題は有りません。

$cdata = $dom->createCDATASection("Hello");
$childnode->appendChild($cdata);
<child><![CDATA[Hello]]></child>

次は実行結果をファイルに保存します

$dom->save("test.xml");

画面に表示したり、変数に格納する場合は次のようにします

$content = $dom->saveXML();
header("Content-Type: text/xml; charset=utf-8");
echo $content;

新しい XML を表示するサンプル

<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

$datanode = $dom->createElement("data");
$root = $dom->appendChild($datanode);

$root->appendChild($dom->createElement("child", "Hello"));
$content = $dom->saveXML();
header("Content-Type: text/xml; charset=utf-8");
echo $content;

ノード値の取得、編集、検索などの方法は次回で説明します。

曜日から日付を調べる

最後の月曜日が何日だったかを調べるケースがあったので
一応メモしておきます。PHP で今日の曜日を知りたい場合

「date("w")」

で取得できます。

返り値は「0~6」の数字で、0 が日曜日、1 が月曜日のようになっています

<?php
function getDateFromDayOfWeek($target){	
  $year	 = date("Y");
  $month = date("m");
  $day	 = date("d");
  $wday	 = date("w");

  if($wday - $target >= 0) {
    $day = $day - ($wday - $target);
  } else {
    $day = $day + ($target - $wday) - 7;
  }
  $time = mktime(0,0,0,$month, $day, $year);
  return date("Y-m-d", $time);
}

$result = getDateFromDayOfWeek(2);
echo $result;

一応関数として作ってあります。
「getDateFromDayOfWeek(曜日を表す数字)」で取得できます。
この場合は 2 なので最後の火曜日の日付が得られるはずです。

Aptana Studio で Ant を使う

Flex SDK 等のビルドをしたい時、Eclipse なら付属の Ant を使うのですが、 Aptana Studio では付属していないようなので、外部ツールとして登録します。 今回使用するツールのバージョンは Aptana Studio 3.2 Apache Ant 1.8.4 です。 まずは Apache Ant をダウンロードします。 http://ant.apache.org/bindownload.cgi あとは展開して設置します。 私は「C:\apache-ant\」としました。 初期設定では外部ツールは非表示なので、「Window」メニューの 「Customize Perspective」から、「Command Groups Availability」タブを選び、 「External Tools」にチェックを入れます。 次は外部ツールとして Ant を登録します。 「Run」メニューから 「External Tools」の「External Tools Configurations」に進み、 「Program」ツリーに新しく設定情報を作成します。 「Name:」は任意の名前、 「Location:」は bin の「ant.bat」の場所、 「Working Directory」はbuild.xml を設置する場所 をそれぞれ記入します。 私の場合は 「Name:」に「Ant」 「Location:」に「C:\apache-ant\bin\ant.bat」 「Working Directory」に「${workspace_loc}${project_path}\」 を指定しました。   「Working Directory」では変数を使い、ワークスペース内の プロジェクトディレクトリ名を指定したので、 各プロジェクトフォルダの直下に build.xml を作ることになります。 あとは build.properties ファイルを作り、External Tools ボタンから Run すればビルドできます。