■2004-06-23
* [Perl] XML::Parser::LiteでTreeスタイル
CPANのSOAP::Liteに同梱のXML::Parser::Liteは、本物のXML::Parserと違ってTreeスタイルやObjectスタイルが使えません。そこでXML::Parser::Liteからもスタイルを利用できるようにXML::Parser::Lite::Styleをこさえてみました。
→下の「XML::Parser::LiteHeavy」を参照してください。
CPANにはXML::Parser::Lite::Treeというのもあるのですが、こちらはXML::Parserとは違った形式で吐き出すようです。これでコンパイラが使えない環境の方でもXML::Simpleが利用できるかも(少なくともバージョン1系は大丈夫そう)。注意点としては、XML::Parserと違いXML::Parser::Liteは'"'や'>'を自動では元に戻してくれないのですが、XML::Parser::Lite::Styleもこれをそのまま引き継いでいます。
* [Perl] XML::Parser::Liteの拡充
XMl::Parser::LiteはXML::Parser同様、パース中にコールバックルーチンを呼び出します。ただし可能なのはInit,Start,Char,End,Finalだけと、些か寂しいものとなっています。それで改造してCdataStart,CdataEnd,Comment,Procまで何とか利用できるようにしました。ふぅ。何が大変って、コールバックルーチンの中でバックトラックが発生する正規表現(同然splitなども)を利用しようとするとPerlがクラッシュするんですね。しかたがないからsubstrで置換処理を実装しました。もう少し拡充したら公開できるかもしれません。ついでに目標としてはPuerPerlなXML::Atom。 XML::Pathを独自につくらないとどうにもならなさそうですが。
* [Perl] XML::Parser::LiteHeavy
XML::Parser::LiteHeavy。XML::Parser::Liteを大幅に改造して、コールバックルーチンで正規表現を使ってもperlがクラッシュしないようにしました。newに渡せるオプションはHandlersの他にStyleとPkg。利用可能なStyleはTreeとObjects(XML::Parser::Style::Objectsをパッケージ名だけかえてそのまま利用)のみです。メソッドにparsefileを追加。元のXMl::Parser::Liteはparserに文字列しか渡せませんでしたが、ファイルハンドルも可能に。たいぶXML::Parserらくしなりました。ずいぶん大きくなってしまったのと、若干パースが遅くなったかもしれないのでHeavyを加えた次第。利用可能なコールバックは結局 Init, Start, Char, End, Final, CdataStart, CdataEnd, Comment, Procとなります。Attlistも含めたいのですが、現状使われている正規表現(リンク先の一番下の方にある"Shallow Parsing in Perl"を参照)では困難なので、この辺りで一区切りつけます。
XML::Parser::Liteで属性値が正しく取得できないバグを直すために今回初めて$^Rという特殊変数を知りました。正規表現内でperlのコードを実行する (?{ code }) の結果を格納する変数だそうで。この辺りは相当苦労しました。myで宣言した変数にblessしたリファレンスを渡そうとしてもなぜかリファレンスではなく単なるクラス名の文字列になってしまうわ、(?{ }) 内でmyを使うとperlがクラッシュするわ……
use XML::Parser::LiteHeavy; use Data::Dumper; my $p = new XML::Parser::LiteHeavy(Style=>'Tree'); my $tree = $p->parse('<foo id="me">Hello!</foo>'); print Dumper($tree); # 結果: $VAR1 = [ 'foo', [ { 'id' => 'me' }, 0, 'Hello!' ] ];