Rust の XML ライブラリを探す
Rust で使える XML 操作ライブラリを探してみたら
⇒ Search Results for 'xml' - Cargo
どうやら xml-rs というのがよく使われているらしい。
An XML library in pure Rust
xml-rs - Cargo
ただ、これ DOM API が使えなくて SAX API だけ。。。
DOM があるといいのになーと思いながらも、とりあえず導入してみた。
今回の環境
Mac OS X El Capitan + Rust 1.9
$ uname -mrsv
Darwin 15.5.0 Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64
$ rustc --version
rustc 1.9.0
$ cargo --version
cargo 0.10.0 (10ddd7d 2016-04-08)
Cargo でプロジェクトを作成
[ヅ] Rust + Cargo で新しくプログラムを書き始める (2016-06-08) と同様に Cargo で新規プロジェクトを作成。
$ cargo new hotentry --bin
$ cd hotentry
$ tree
.
├── Cargo.toml
└── src
└── main.rs
Cargo.toml に依存 crate を記述。
Cargo.toml に今回使うライブラリである hyper (HTTP通信ライブラリ) と xml-rs (XML操作ライブラリ) を記述。
$ cat Cargo.toml
[package]
name = "hotentry"
version = "0.1.0"
authors = ["Nick Labadie <info@nilab.info>"]
[dependencies]
hyper = "0.9.6"
xml-rs = "0.3.4"
ソースコード
今回は、はてなブックマークはてなブックマークのホッテントリ をコンソールに出力するサンプルコードを書いた。
参考資料はこのへん。
- hyper のリファレンス: hyper - Rust
- xml-rs のリファレンス: xml - Rust
Rust の標準ライブラリの資料。
サンプルコード。
$ cat src/main.rs
extern crate hyper; // http client
extern crate xml; // xml parser
use std::io::BufReader;
use hyper::Client;
use hyper::client::response::Response;
use hyper::error::Result;
use xml::reader::{EventReader, XmlEvent};
// いわゆるクラス的なもの
pub struct Feed {
// フィールドに String 型の変数を持たせる
url: String
}
impl Feed {
// コンストラクタ
// いわゆるクラスメソッドとして実装する
pub fn new(url: &str) -> Feed {
Feed{
url: url.to_string()
}
}
// フィードのエントリのタイトルとURLを取得する
// いわゆるインスタンスメソッドは、第一引数に &self を指定する
fn get_item_list(&self) -> (Vec<String>, Vec<String>) {
// フィードを取得
let feed = Feed::get_feed(self.url.as_str());
match feed {
Ok(v) => {
// フィードからタイトルとURLを抜き出す
return Feed::extract_item_list(v);
}
Err(e) => {
println!("Error: {}", e);
// エラーのときは空っぽの配列を返す
return (Vec::new(), Vec::new());
}
}
}
// RSS フィードを取得
fn get_feed(url: &str) -> Result<Response> {
// hyper を使って HTTP 通信
let client = Client::new();
let response_builder = client.get(url);
let result = response_builder.send();
return result;
}
// RSSフィードからタイトルとURLを抜き出す
// 動的配列 Vec が2つ入ったタプルを返す
fn extract_item_list(res: Response) -> (Vec<String>, Vec<String>) {
// タイトルとURLを保持する動的配列
let mut title_list = Vec::new();
let mut link_list = Vec::new();
// xml-rs を使って XML をパース
let buf = BufReader::new(res);
let parser = EventReader::new(buf);
let mut in_item_elem = false;
let mut in_title_elem = false;
let mut in_link_elem = false;
// 懐かしい XML SAX API
// DOM API は無かった。。。
for elem in parser {
match elem {
// 開始タグ
Ok(XmlEvent::StartElement { name, .. }) => {
match name.local_name.as_str() {
"item" => in_item_elem = true,
"title" => in_title_elem = true,
"link" => in_link_elem = true,
_ => {}
}
}
// 終了タグ
Ok(XmlEvent::EndElement { name }) => {
match name.local_name.as_str() {
"item" => in_item_elem = false,
"title" => in_title_elem = false,
"link" => in_link_elem = false,
_ => {}
}
}
// コンテンツ
Ok(XmlEvent::Characters(text)) => {
if in_item_elem {
if in_title_elem {
title_list.push(text.trim().to_string());
} else if in_link_elem {
link_list.push(text.trim().to_string());
}
}
}
Err(e) => {
println!("Error: {}", e);
break;
}
_ => {}
}
}
return (title_list, link_list);
}
}
fn main() {
// はてなブックマークのホッテントリRSSフィード
let url = "http://feeds.feedburner.com/hatena/b/hotentry";
// struct Feed のインスタンスを生成
let f = Feed::new(url);
// Feed の get_item_list をコールして、
// 動的配列の2つ入ったタプルを取得
let (title_list, link_list) = f.get_item_list();
// タイトルとURLを出力
for (n, title) in title_list.iter().enumerate() {
println!("{}\n{}\n", title, link_list[n]);
}
}
リリースビルド
cargo build --release コマンドで、リリース用のバイナリファイルを生成することができる。
$ cargo build --release
Compiling httparse v1.1.2
Compiling winapi-build v0.1.1
(中略)
Compiling cookie v0.2.4
Compiling hyper v0.9.6
Compiling hotentry v0.1.0 (file:///Users/hoge/hotentry)
実行ファイルは target/release 以下に配置される。
$ file ./target/release/hotentry
./target/release/hotentry: Mach-O 64-bit executable x86_64
実行結果
こんな感じでちゃんと出力できた。
$ ./target/release/hotentry
リニア中間駅は奈良 JR東海「京都だとカーブきつい」:朝日新聞デジタル
http://www.asahi.com/articles/ASJ6865HLJ68OIPE02F.html
ブコメに/いれて違う話するの止めろ
http://anond.hatelabo.jp/20160609192302
(以下略)
-
ref.
- The Rust Programming Language
- hyper.rs
- GitHub - netvl/xml-rs: An XML library in Rust
- [ヅ] プログラミング言語 Rust のインストールと Hello World (Mac OS X) (2016-04-04)
- [ヅ] Rust + Cargo で新しくプログラムを書き始める (2016-06-08)
tags: rust
Posted by NI-Lab. (@nilab)