« さくらインターネットサーバでpear (厄介なバージョンに当たった人向け) | トップページ | 今日のお題:「祝日判定」 »

PEARのXML_Parserを使ったXMLパーサのクラス化(というか、移行方法)

PHPのXMLパーサをクラスで使おうとすると、難しいというか、簡単にはうまくいきません。
すでにxml_parseとか使って書いちゃったよ!って場合、泣かされてしまうところです。
けど、PEARのXML_Parserを使うと、移行がわりと簡単にできます。

まず、以前のようにXMLパーサ関数を使った処理の流れは大体こんなかんじ。
・要素の開始・終了時の処理、cdata(文字データ)の処理を行うハンドラ関数を作成する
・xml_parser_create() でXMLパーサを作成
・xml_set_element_handler() で、要素の開始・終了のハンドラを定義する
・xml_set_characer_data_handler() で、cdataハンドラを定義する
・xml_parse() で、XMLドキュメントの処理
・xml_parser_free() でXMLパーサの解放

手抜きしてるけど、ソースコードを例にするとこんなかんじ。
まず、xmlパース処理を呼び出すところをこんなかんじで作っております。

  $xmlparser = xml_parser_create() ;
xml_set_element_handler( $xmlparser ,
"xmlparse_h_element_start" ,
"xmlparse_h_element_end" ) ;
xml_set_character_data_handler( $xmlparser ,
"xmlparse_h_data" ) ;
$res = xml_parse( $xmlparser , $xmldata ) ;
xml_parser_free( $xmlparser ) ;

あとは、ハンドラの定義がこんなかんじにしてあるとして。
function xmlparse_h_element_start ( $parser , $name , $attrs )
{
/* 中略。ここで element の開始(開きタグ)処理 */
}
function xmlparse_h_element_end( $parser , $name )
{
/* 中略。ここで element 終了(閉じタグ)処理 */
}
function xmlparse_h_data( $parser , $data )
{
/* 中略。ここで 文字データ処理 */
}

これを、移行する方法は、こんなかんじ。
・XML_Parserの派生クラスを作る
・コンストラクタ(__construct)で、最後に「parent::XML_Parser」を呼ぶとき(必ず呼ぶこと!)、2番目の引数を 'event' にするのを忘れない。
・xml_set_element_handler()で定義した要素開始のハンドラ関数の中身を、 startHandler メンバ関数に持ってくる
・xml_set_element_handler()で定義した要素終了のハンドラ関数の中身を、 endHandler メンバ関数に持ってくる
・xml_set_characer_data_handler() で定義したcdataハンドラ関数の中身を、cdataHandler メンバ関数に持ってくる
・必要に応じて、グローバル変数とかを使ってた部分をクラス変数に変更するなど、修正する
・他から呼ぶときは、普段のクラスの呼び出しと同じ。
 ・初期化:$xmlp = new MyXmlPaser( 'UTF-8' , 'UTF-8' ) ;
 ・入力データのセット:$xmlp->setInputString( $xmldata ) ;
 ・XML処理実行:$xmlp->parse() ;

クラス部分はこんなかんじ。

require_once 'XML/Parser.php' ;

class MyXmlPaser extends XML_Parser
{
function __construct( $ca_srcenc , $ca_dstenc ) {
parent::XML_Parser( $ca_srcenc , 'event' , $ca_dstenc ) ;
}
function startHandler ( $ca_parser , $ca_name , $ca_attrs )
{ /* element start 処理 */
}
function endHandler( $ca_parser , $ca_name )
{
/* element end 処理 */
}
function cdataHandler( $ca_parser , $ca_data )
{
if ( $ca_data == FALSE ) {
} else {
/* cdata 処理 */
}
}
}

呼び出す本体をまとめるとこう。
$xmlp = new MyXmlPaser( 'UTF-8' , 'UTF-8' ) ;
$xmlp->setInputString( $xmldata ) ;
$xmlp->parse() ;

なお、基底クラスの XML_Parser でどんなことしてるかは、PEARディレクトリの XML/Parser.php にすべて書いてあるので、わからなくなったら目を通すといいと思います。

この移行によって、大幅に処理の追加や変更をする場所は(基本的に)ありません。
クラス化することによって、全部クラスに集約できるので、グローバル変数で扱うことがなくて、楽になりました。

|

« さくらインターネットサーバでpear (厄介なバージョンに当たった人向け) | トップページ | 今日のお題:「祝日判定」 »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: PEARのXML_Parserを使ったXMLパーサのクラス化(というか、移行方法):

« さくらインターネットサーバでpear (厄介なバージョンに当たった人向け) | トップページ | 今日のお題:「祝日判定」 »