CPANモジュール

せっかくMENTA紹介して頂いたのに、インストールしたまま放置で申し訳ないです。まだまだ基礎知識が不足しているので、段階を踏んでチャレンジします。XMLをいじりたいので、CPANモジュールを使ってみることにしました。(MENTAにXpathEngineが入ってるんですが、マニュアルがなくてよく分かりませんでした。探し方が悪い?)

XML::XPathをインストール

叩いたあと、インタラクティブな質問がありますが、すべてデフォルトです。

# perl -MCPAN -e shell

cpan>」プロンプトが表示されたらインストールします。関連モジュールも一緒にインストールしてくれます。

cpan> install XML::XPath

処理対象データの準備

面白そうなのでiTunesのデータを使うことにします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Major Version</key><integer>1</integer>
	<key>Minor Version</key><integer>1</integer>
	<key>Application Version</key><string>8.1.1</string>
	<key>Features</key><integer>5</integer>
	<key>Show Content Ratings</key><true/>
	<key>Music Folder</key><string>file://localhost/C:/Documents%20and%20Settings/user/My%20Documents/My%20Music/iTunes/iTunes%20Music/</string>
	<key>Library Persistent ID</key><string>174E7BE44310E1A3</string>
	<key>Tracks</key>
	<dict>
		<key>2293</key>
		<dict>
			<key>Track ID</key><integer>2293</integer>
			<key>Name</key><string>Aminjing Nebere(I Trusted You) Joakim's Afrobot Mix</string>
			<key>Artist</key><string>Clashing Egos</string>
			<key>Album</key><string>Cisco House presents Compact Vinyl2</string>
			<key>Genre</key><string>Electronica/Dance</string>
			(snip)
		</dict>
		(snip)
	</dict>
</dict>
</plist>

処理プログラムの作成

処理対象データのパスとXPathを入力して、処理対象データへのXPath適用結果を出力するプログラムを作ります。

#!/usr/bin/perl

use strict;
use warnings;
use Encode;
use XML::XPath;
use XML::XPath::XMLParser;

# ファイルとXPathクエリを解析するオブジェクトを作成します
my $xpath = XML::XPath->new( filename => shift @ARGV );

# コマンドラインに指定されたパスを適用して、一致するノードリストを取得します
my $nodeset = $xpath->find( shift @ARGV );

# リスト内の各ノードを出力します
foreach my $node ( $nodeset->get_nodelist ){
        print encode( 'utf-8',XML::XPath::XMLParser::as_string( $node ) ) . "\n";
}

実行結果

入力

$ ./xml_pull.pl data.xml "/plist/dict/dict[contains(./dict/strings,Cisco)]"

出力(一応、動作しますが、今後のことを考えたらデータ構造は見直した方が良さそうです。)

<dict>
		<key>2293</key>
		<dict>
			<key>Track ID</key><integer>2293</integer>
			<key>Name</key><string>Aminjing Nebere(I Trusted You) Joakim's Afrobot Mix</string>
			<key>Artist</key><string>Clashing Egos</string>
			<key>Album</key><string>Cisco House presents Compact Vinyl2</string>
			<key>Genre</key><string>Electronica/Dance</string>
			(snip)
		</dict>
		(snip)
</dict>

コードもデータも全部パクリですけど、ここに来るまで時間かかりました。1年ぶりにXPath書いてみましたが、データ構造が特殊だった(これが普通?)ので、戸惑うことが多かった。