単純な構造のXMLからエレメントを抜き出す 4月27日, 2012


GPXデータのtrkpt要素を抜き出し、time要素を読み取って処理することで遊ぶうち、その一部は幾分かでも汎用的なものにしておいて後日に備えようという気になった。XMLのうち、ごくシンプルな構造のものであればそれほど手もかからないという読みだ。

エレメントの名称と対象のXMLファイルを指定すると、そのエレメントの内容を表示する単純なperlのスクリプトだ。XMLでは、ツリー構造の各レベルに同一名称のエレメントが存在している場合がある。ここではそのレベルの違いを無視し、名称で全てを抜き出してくる。特徴は、XMLモジュールを用いず、正規表現でマッチさせている点にあるだろう。ただし、私の関心は身の回りにある ごく単純な構造のXMLファイル にあるので、それなりに複雑でサイズも大きい純然たるXMLには対応できないだろうと思う。また、XML宣言部分や全角のタグ名称についてはここでは考慮していない。

スクリプトでは、複数行マッチをさせる関係から予め全てを文字列に読み込んでしまう。サブルーチンでそこから該当エレメントを配列に抜き出させ、その配列を表示している。この表示部分を加工すれば、後日何かに適応できるのではないかという目算だ。でも何ができるかわからないけどね。サブルーチンで、マッチングをとるのにちょっと格好悪い’or’があるのは、<tag…/>を処理するためのもの。そこでは属性にデータがあり終了タグが省かれている。どうも私はXMLを充分に理解していないなあ。とにかくそれに対応している。見るからに効率も悪そうだしエレガントではないのだが、わが要求からすれば充分に機能を果たしてくれる(はず)。

$ ./extract_element.pl ElementName From.xml

ElementNameが抜き出すエレメント名、From.xmlが対象のXMLファイル名。

[追記 2014-02-13]: タイポが残っていた。訂正。まじめに動作確認もしなかったようだ。それと、’plist’をこれでいじっていたら、単純な構造であっても同名のエレメントが内部に存在すると処理できないこと、awkなら同名エレメント以外簡単に処理することに気づいた。

$ awk '/<ElementName>/,/\/ElementName>/ {print}' From.xml

今更だね。GPXのデータを見ている時、なぜこんな簡単なことに気づかなかったのだろう。執着すると離れて考えられなくなる典型だな。