人文学向け電子テキストガイドラインTEI/XMLに準拠したファイルをPHPで処理するにあたって

人文学向け構造化ルールであるTEI/XMLガイドラインに準拠して作成したファイルは、とにかく色んな方法で処理して その都度必要な状態にして利用できるのが魅力です。それについて書き始めると長くなるので詳しくは 以下のページなどをご覧ください。

bungaku-report.com

なお、この記事は、PHPプログラミングをかなりやりこんでいる人向けで、TEI/XMLガイドラインに準拠した ファイルを処理するのに必須の知識ではありませんので、PHPをやってない人はここでお帰りいただく(?)のが 正しい時間の使い方だと思います。

ここでは、最近久しぶりにPHPで処理することになり、いくつかうろ覚えだったことに再びつまづいたので 忘れても大丈夫なようにここにメモしておくことにしました。(同様の理由でこのブログには DHに関連する開発についてのTipsが大量にため込まれていますので困った時にはこのブログで 検索してみていただくと解決策が見つかるときもあるかもしれません)。

さて、今回は、PHPでxpathがうまく通らない、という問題につきあたりました。基本的に、PHPで XMLファイルを処理するときは、simpleXMLかDOMDocument を使うのですが、どちらでも うまくいかず、うーん、となっておりました。

なお、最近は、 Zend_Dom_Queryというのがあるそうで、 これを使えばCSSセレクタでも処理できてしまうらしいので、PythonのBeautifulsoup並みに簡単に処理できるかもしれません。

それから、ここでなぜPHPを使っているのかというと、一部でPostgreSQLを使ってしまっていたりして全体としてまだPHP脳に 頼らざるを得ない状況になっているためです。PHPに深入りしていない人はPythonのBeautifulsoupとか Javascriptとか使っていただくのが幸せへの道だと思います。

それはともかく、しばらくあれこれ試行錯誤していて思い出したのは、名前空間の設定です。 xmlnsがついているXMLファイルは明示的に名前空間を設定しなければならなかったのでした。 たとえば以下のような感じです。

$xml = simplexml_load_file("zz2_new.xml");
$xml->registerXPathNamespace('tei', 'http://www.tei-c.org/ns/1.0');
$xml->registerXPathNamespace('xml', 'http://www.w3.org/XML/1998/namespace');

こうしておくと、たとえばこの後、以下のような感じで指定したIDを持つエレメントを取りだして処理することができます。

$pid = "TP11";
$eperson = $xml->xpath("//tei:person[@xml:id='$pid']");

なお、上記の$epersonを再度xpathで処理したい場合は、改めてregisterXPathNamespace() する必要があるようです。

大した話ではないのですが、忘れてハマると大変で、しかし、知っていれば一瞬で通り抜けられることなので、 一応メモしておきます。(メモしたことを忘れないようにしないといけませんね。)