PHPのsimplexmlでハマる

PHPでXMLファイルを使用する必要がありました。
多段階層のデータを参照配列で扱いたいのです。
PHPでXMLファイルを作成して、Perlのスクリプトで使用するというプロセスです。
PHPのセッションに格納しておいて、セッションファイルを直接読みに行かせるなども考えたのですが、
メンテナンスを考えて結局XMLファイルを用意する方法に決定。

XMLファイルをPHPで読み直す際に問題が発生。
ノードがオブジェクトのまま、simpleXMLElementになっていて扱いづらい。
単階層の場合は、(string)$hogeとか、“$hoge”とかするだけで何とかなるのですが、多段階層の場合はそうもいきません。
他に構造を扱う関数としてjson_decode(json_encode($hoge),true)で何とかなるかと思いきや、空値が配列になってしまう問題が発生。空値用の特別文字「{empty}」などを用意してみたりしても、判定を追加する箇所が多すぎで挫折。
さらに、「<!CDATA[fuga]]>」も配列になることが判明、まったく使い物になりませんでした。

最終的には、ドキュメントで何を言っているのかよくわからなかったパラメータを適当に採用していたら、希望する動作を見せたので落ち着きました。
結局はこうなりました。
simplexml_load_file( $set_file, 'simpleXMLElement', LIBXML_NOCDATA )

PHPは、関数の動作がこうもいい加減なものが多いですね。
互換のためにいろんなパラメータが追加されたり、関数名が変更になったりと振り回され続けるしかないですね。

XML::Simple(PerlでXMLをパースする)

Ajaxへの熱が冷めはじめた昨今、しかしXMLファイルを扱う機会はあまり減りません。
使用したXML::Simpleモジュールのバージョンは2.18でした。
Perlのバージョンが5.8であれば、インストールされています。

使い方

my $xml = <<'XML';
<?xml version="1.0" encoding="UTF-8"?>
<urlset>
  <url>http://127.0.0.1/</url>
  <title>localhost</title>
  <copyright>Administrator</copyright>
</urlset>
XML
use XML::Simple;
my $xs = new XML::Simple();
my $parser = $xs -> XMLin( $xml );
my %parse = (
  'uri'       => $parser -> {'uri'},
  'title'     => $parser -> {'title'},
  'copyright' => $parser -> {'copyright'},
);
use utf8;
foreach my $key ( keys %parse ){
  utf8::encode( $parse{$key} );
  printf( "%s : %s\n", $key, $parse{$key} );
}

不具合

エンコードが正しく指定されていても、UTF-8以外であれば受け付けてくれません。

おわりに

結果の文字列にBOMを付けるという余計な事をするため、
utf8::encodeでBOMを除去する処理が必要になってしまいます。
スイッチをつけるなどして、選べるようにしてほしい。

更新履歴

2008-04-04
サイト移動に伴うHTMLの修正(旧URI:[廃止])
2008-01-07
公開

XML/RSS(PHPでRSSをパースする)

RSSファイルを参照し、オリジナルのリーダーを作成します。
RSSの解説は、RSSによるサイトの情報の要約と公開を参考にしました。
XML_RSSパッケージの解説は、XML_RSSを参考にしました。
使用したXML_RSSパッケージのバージョンは1.14(0.9.10)でした。
XML_RSSパッケージは、PHPのバージョン5.2.1ではインストールされていません。

インストール方法

XML_RSSをインストールすると、XML_Treeも同時にインストールされます。

pear install -a XML_RSS

サンプル

http://pear.php.net/のRSS

構文

<?php
require_once( "XML/RSS.php" );
// RSSファイルのURL
$rss = new XML_RSS( "http://pear.php.net/feeds/latest.rss" );
// RSSのパース
$rss -> parse();
// channnelタグ出力
$channel = $rss -> getChannelInfo();
printf( "<html>\n<head>\n\t<title>RSS - %s</title>\n</head>\n",
  $channel['title']
);
printf( "<h1><a href=\"%s\">%s</a></h1>\n<p>%s</p>\n",
  $channel['link'],
  $channel['title'],
  $channel['description']
);
// imageタグ出力
if( isset( $rss -> images ) ){
  foreach( $rss -> getImages() as $image ){
    if( !count($image) ){ continue; }
    printf( "<p><a href=\"%s\"><img src=\"%s\" alt=\"%s\" align=\"right\"></a></p>\n",
      $image['link'],
      $image['url'],
      $image['title']
    );
  }
}
// itemタグ出力
echo "<dl>\n";
foreach( $rss -> getItems() as $item ){
  printf( "\t<dt><a href=\"%s\">%s</a></dt>\n\t\t<dd>%s</dd>\n",
    $item['link'],
    $item['title'],
    isset( $item['description'] ) ? $item['description'] : ""
  );
}
echo "</dl>\n";
// HTMLの出力終了
echo "</body>\n</html>";
?>

更新履歴

2008/04/04
サイト移動に伴うHTMLの修正(旧URI:[廃止])
2007/07/31
PHPXML_RSSとあわせるための細かな修正
2007/07/30
公開