重要.
Rubyインタプリタには、このページで紹介しているNQXMLではなく、REXMLが採用されました。REXMLの使い方はRubyでXML (REXML)を参照。
RubyでXML文書を読み書きしてみる。
Rubyの標準ライブラリにはXMLパーサーは含まれていない。Rubyで使えるXMLパーサーには,次のものがある。
このうち,NQXMLはpure-Rubyで,メンテナンスもされているようなので,これを使ってみる。
次のようなXML文書をスキャンしてみる。
<?xml version="1.0" encoding="EUC-JP"?>
<?ruby
class Foo
def fn(x)
x * 2
end
end
?>
<!DOCTYPE hoge>
<hoge>
<foo atr="2" bar="<">This is a pen.</foo>
Plain. 日本語
<!-- コメント -->
<content xml:lang="ja">
<![CDATA[<cdata>テスト]]>
< コンテント ! !
</content>
<br />
</hoge>
<!-- コメント -->
タグ,文字データのほか,XML宣言,文書型宣言,処理命令,CDATAセクションを含み,実体参照,文字参照も使っている。
NQXMLでXML文書を読むとき,イテレータを使う方法と,DOMを使う方法がある。まずはイテレータから。
4| require 'nqxml/streamingparser' 5| 6| parser = nil 7| File.open("xmlsample.xml", "r") {|f| 8| parser = NQXML::StreamingParser.new(f) 9| } 10| i = 0 11| parser.each {|entity| 12| str = entity.to_s.strip 13| next if entity.instance_of?(NQXML::Text) && str == "" 14| i += 1 15| print "#{i}: #{str} #<#{entity.class}>\n" 16| }
で,実行結果。
1: <?xml version="1.0" encoding="EUC-JP"?> #<NQXML::XMLDecl>
2: <?ruby
class Foo
def fn(x)
x * 2
end
end
?> #<NQXML::ProcessingInstruction>
3: <!DOCTYPE hoge> #<NQXML::Doctype>
4: <hoge> #<NQXML::Tag>
5: <foo bar="<" atr="2"> #<NQXML::Tag>
6: This is a pen. #<NQXML::Text>
7: </foo> #<NQXML::Tag>
8: Plain. 日本語 #<NQXML::Text>
9: <!-- コメント --> #<NQXML::Comment>
10: <content xml:lang="ja"> #<NQXML::Tag>
11: <cdata>テスト #<NQXML::Text>
12: < コンテント ! ! #<NQXML::Text>
13: </content> #<NQXML::Tag>
14: <br> #<NQXML::Tag>
15: </br> #<NQXML::Tag>
16: </hoge> #<NQXML::Tag>
17: <!-- コメント --> #<NQXML::Comment>
XML文書内で次の表の左に挙げる項目が出現したときに,右に挙げるクラスのオブジェクトがブロックに渡される。
| 項目 | クラス |
|---|---|
| 文字データ,CDATAセクション,参照 | NQXML::Text |
| 開始タグ,終了タグ,空要素タグ | NQXML::Tag |
| XML宣言 | NQXML::XMLDecl |
| 文書型宣言 | NQXML::Doctype |
| 処理命令 | NQXML::ProcessingInstruction |
| コメント | NQXML::Comment |
CDATAセクション,実体参照(<など),文字参照(!,!)は,あらかじめ展開されて文字データとして扱われる。参照は文字データに埋め込まれるが,CDATAセクションは独立したオブジェクトとなる。
属性値に含まれる参照も展開される。
空要素タグは,開始タグと終了タグに展開され,二つのオブジェクトとなる。
タグの要素名は,NQXML::Tag#nameメソッドで,属性はNQXML::Tag#attrsで取り出す。属性は,開始タグはHash(属性がないときは{}),終了タグはnilが返る。