PHPマニュアル より。。。注意: この拡張は実験的なものではありません。しかしながら、PHP 5 では決してリリースされないでしょう。また、PHP 4 でのみ配布されます。 もし PHP 5 でDOM XML をサポートする必要がある場合、 DOM 拡張を使用することができます。 この domxml 拡張は DOM 拡張と互換性はありません。
PHPでもDOM XML関数を使ってXMLファイルの操作を行うことができますが、ノードだ要素だ属性だ、なんてコーディングが結構面倒ですよね。Javaの場合、以前からRelaxer(RELAXで定義されたXMLモデルに従ったXMLドキュメントを操作するためのJavaクラスを自動生成するプログラム)を使ってアクセスクラスを自動生成し、それを使ってXMLにアクセスしていますが、コーディングの際に「XMLを操作している」という意識を持つ必要がほどんどない(メソッド「get[要素名]やget[属性名]」で取得できる)ので、非常に重宝しています。
やっぱり、PHPでもこんなのがあったら便利だよなぁ。。。ということで、以前作成したサンプルを元に、「PHP4.3.0用XMLアクセスクラスを自動生成するプログラム」を作り始めてみました。とりあえず第一弾として「既存のXMLを読み込み、それにアクセスするクラスを自動生成する」クラスです。
まず、説明に先立って、開発と確認の環境ですが、以下の通りです。
Vine Linux 2.1.5(ftp版)
Apache 1.3.24(ソースからインストール)
PHP4.3.0dev(2002/05/31にPHP本家のcvsからソースを取得&インストール)
libxml2-2.4.21(ソースからインストール)
さていきなり本題ですが、「どんなXMLからどんなPHPクラスができるか?」ですが、以下のようなXMLドキュメントを考えてみます。
●XMLドキュメント
<?xml version="1.0"?>
<article attr1="php" attr2="domxml">
<subject>PHP関連書籍</subject>
<book>
<title>PHP4徹底攻略</title>
<isbn>ISBN4-7973-1392-7</isbn>
</book>
<book>
<title>Dynamic Webサイト構築入門 PHP編</title>
<isbn>ISBN-4898142818</isbn>
</book>
<book>
<title>Oracle8iとPHPで作るWebデータベースfor Miracle Linux</title>
<isbn>ISBN4871938670</isbn>
</book>
<book>
<title>PHPパーフェクトリファレンス</title>
<isbn>ISBN-4894714027</isbn>
</book>
</article>
このXMLドキュメントから作成されるクラスは、XMLドキュメントに含まれる要素(タグ)毎のクラス(以下の5つ)になります。
Article
Book
Isbn
Subject
Title
例として、ArticleクラスとTitleクラスのPHPソースは、以下のような感じになります。
●Article.phl
<?php
require_once("Subject.phl");
require_once("Book.phl");
class Article
{
var $obj_;
function Article($obj, $mode = "file")
{
$mode = strtolower($mode);
if ($mode == "file") {
$dom = domxml_open_file($obj);
$this->obj_ = $dom->document_element();
}
else if ($mode == "string") {
$dom = domxml_open_mem(mb_convert_encoding($obj, "utf-8", "auto"));
$this->obj_ = $dom->document_element();
}
else if ($mode == "obj") {
$this->obj_ = $obj;
}
else {
die("not supported mode [$mode] !");
}
}
function getAttr1() { return $this->obj_->get_attribute("attr1"); }
function getAttr2() { return $this->obj_->get_attribute("attr2"); }
function getSubject()
{
$ret = array();
$elements = $this->obj_->get_elements_by_tagname("subject");
for ($i = 0; $i < count($elements); $i++) {
array_push($ret, new Subject($elements[$i], "obj"));
}
if (count($ret) == 1) {
$ret = $ret[0];
}
return $ret;
}
function getBook()
{
$ret = array();
$elements = $this->obj_->get_elements_by_tagname("book");
for ($i = 0; $i < count($elements); $i++) {
array_push($ret, new Book($elements[$i], "obj"));
}
if (count($ret) == 1) {
$ret = $ret[0];
}
return $ret;
}
function getContent() { return mb_convert_encoding($this->obj_->get_content(), mb_internal_encoding(), "auto"); }
}
?>
●Title.phl
<?php
class Title
{
var $obj_;
function Title($obj, $mode = "file")
{
$mode = strtolower($mode);
if ($mode == "file") {
$dom = domxml_open_file($obj);
$this->obj_ = $dom->document_element();
}
else if ($mode == "string") {
$dom = domxml_open_mem(mb_convert_encoding($obj, "utf-8", "auto"));
$this->obj_ = $dom->document_element();
}
else if ($mode == "obj") {
$this->obj_ = $obj;
}
else {
die("not supported mode [$mode] !");
}
}
function getContent() { return mb_convert_encoding($this->obj_->get_content(), mb_internal_encoding(), "auto"); }
}
?>
何となく分かるでしょうか?作成されるクラスでは、
メソッド「get[要素名]」で子要素オブジェクトを返す。子要素が複数ある場合は、子要素オブジェクトの配列として返す
メソッド「get[属性名]」で属性値を返す
メソッド「getContent」でテキストを返す
必要な別クラスファイルは、自動的にrequire_onceされる
となっています。
また、これら自動生成されたクラスを使ったサンプルは、以下のようになります。内容は、各要素の属性?テキストを順に一覧表示するものです。ここでは、DOM XML関数を一切使用していない&要素?属性の区別がなく全てgetXxxだけででアクセスできていることが分かると思います。
●test.php
<?php
require_once("phl/Article.phl");
?>
<?php
function doIt($root)
{
echo $root->getAttr1() . "<br/>";
echo $root->getAttr2() . "<br/>";
$subj = $root->getSubject();
echo $subj->getContent() . "<br/>";
$books = $root->getBook();
for ($i = 0; $i < count($books); $i++) {
$title = $books[$i]->getTitle();
echo $title->getContent()."<br/>";
$isbn = $books[$i]->getIsbn();
echo $isbn->getContent()."<br/>";
}
}
/**
* main
*/
unset($root);
$root = new Article("domxml.xml");
doIt($root);
$root = null;
?>
●出力結果
phpdomxmlPHP関連書籍PHP4徹底攻略ISBN4-7973-1392-7Dynamic Webサイト構築入門 PHP編ISBN-4898142818Oracle8iとPHPで作るWebデータベースfor Miracle LinuxISBN4871938670PHPパーフェクトリファレンスISBN-4894714027
自動生成プログラムの方ですが、上記XMLファイルとテストスクリプトを含めたアーカイブをダウンロードできるようにしてありますので、このページの一番上にあるリンクからダウンロードしてください。
使い方(?)の簡単な説明ですが、以下のようにDOM2PHPクラスにXMLファイル名を指定してインスタンス化し、executeメソッドを呼ぶだけで直下のphlディレクトリにファイルが作成されます。もちろん、Apacheの実行User/Groupでファイルを作成できるよう、phlディレクトリへのpermissionの設定が必要です。
●DomCodeGen.php
<?php
ini_set("include_path", "../../");
require_once "jp/ne/hi_ho/pat/dimension/xml/dom/DOM2PHP.phl";
?>
<?php
if (!isset($_GET["xml"])) {
die("no parameter 'xml' !!");
}
$d2p = new DOM2PHP($_GET["xml"]);
$d2p->execute();
?>