パーサを使って解析
今までのサンプルでドキュメントを取得できることがわかりました。しかし,
そこで,
FlickrのAtomはリスト3のようになっています。
リスト3 Flickr Atomの例
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:flickr="urn:flickr:"
xmlns:media="http://search.yahoo.com/mrss/">
<title>Uploads from yuichi.sakuraba</title>
<<省略>>
<entry>
<title>Entremet Montebello, Pierre Hermé, Nihonbashi Mitsukoshi</title>
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/skrb/3224086417/"/>
<id>tag:flickr.com,2005:/photo/3224086417</id>
<published>2009-01-25T07:08:47Z</published>
<updated>2009-01-25T07:08:47Z</updated>
<dc:date.Taken>2008-12-22T20:39:03-08:00</dc:date.Taken>
<content type="html"> ... <img src="http://farm4.static.flickr.com/3531/3224086417_896092041b_m.jpg" ... </content>
<<省略>>
</entry>
<<省略>>
</feed>
<feed>タグの中に複数の<entry>タグがあり,
ここでは,
以下にAtomの読み込みとパースを行うAtomReaderクラスのAtom読み込み部分を示します。
リスト4
public class AtomReader {
public-init var url: String;
public function read(): Void {
var request = HttpRequest {
location: url
// 入力の解析はparse関数で行う
onInput: parse
// エラー処理
onException: function(ex: Exception) {
println("exception: {ex.getMessage()}");
}
};
request.enqueue();
}
read関数では,
では,
リスト5
// 処理が終了した後にコールするコールバック関数
public var onDone: function(:PhotoInfo[]): Void;
// サムネイルのURLを取り出すための正規表現
def pattern = java.util.regex.Pattern.compile("http://farm.*_m.jpg");
// Atomのパース
function parse(stream: InputStream) {
var infos: PhotoInfo[];
var info: PhotoInfo;
var inEntry: Boolean;
var parser = PullParser {
documentType: PullParser.XML;
input: stream
onEvent: function(event: Event) {
if (event.type == PullParser.START_ELEMENT) {
if (event.qname.name == "entry") {
// <entry>の開始
// 新たなPhotoInfoオブジェクトを生成する
inEntry = true;
info = PhotoInfo {};
}
}
if (event.type == PullParser.END_ELEMENT) {
if (event.qname.name == "entry") {
// </entry>の場合
// 作成したPhotoInfoオブジェクトをシーケンスに追加
inEntry = false;
insert info into infos;
} else if (inEntry and event.qname.name == "title") {
// </title>の場合
// PhotoInfoオブジェクトのtitleを設定
info.title = event.text;
} else if (inEntry and event.qname.name == "content") {
// </content>の場合
// 正規表現を用いて,サムネイルのURLを取り出し,
// PhotoInfoオブジェクトのthumbnailUrlに設定
var matcher = pattern.matcher(event.text);
if (matcher.find()) {
var url = matcher.group();
info.thumbnailUrl = url.replaceAll("_m", "_t");
}
}
}
}
}
// パースの開始
parser.parse();
if (onDone != null) {
// パースが終了したら,コールバック関数をコールする
onDone(infos);
}
stream.close();
}
PullParserクラスはイベント駆動型のパーサで,
PullServerオブジェクトがパースするドキュメントの種類はdocumentTypeアトリビュートで指定します。ここには,
パース時のイベントはonEventアトリビュートに設定した関数で行われます。引数としてjavafx.
ここでは,
そして,
ここで取得できるURLはhttp://
_mの場合イメージの長辺が240ピクセルと少し大きいので,
<entry>要素のEND_
パースが終了したら,