要約
ストリーム式の XML パーサ。
rexml の XML パーサの中では高速ですが、機能は限定的です。もう少し高機能なストリーム式パーサが必要な場合は REXML::Parsers::SAX2Parser を用いてください。
パーサからはコールバックによってパースした情報を受け取ります。 REXML::StreamListener を include し、必要なメソッドをオーバーライドしたクラスのオブジェクトをコールバックオブジェクトとして REXML::Parsers::StreamParser.new に渡します。
REXML::Parsers::StreamParser#parse を呼び出すとパースが開始しその結果によってコールバックが呼び出されます。
コールバックされるメソッドは REXML::StreamListener になにもしないメソッドとして定義されています。どのようなコールバックがあるかはそちらを参照してください。
パーサはXML文書の各構成要素を前から順に処理し、その順にコールバックメソッドを呼び出します。順が前後することはありません。
StreamParserの例
この例では tag_start と text をオーバーライドして開始タグとテキストの情報を受け取れるようにしています。空白や改行もテキストであることに注意してください。
require 'rexml/parsers/baseparser'
require 'rexml/parsers/streamparser'
require 'rexml/streamlistener'
class Listener
include REXML::StreamListener
def initialize
@events = []
end
def text(text)
@events << "text[#{text}]"
end
def tag_start(name, attrs)
@events << "tag_start[#{name}]"
end
attr_reader :events
end
xml = <<EOS
<members>
<member name="apple" color="red">
<comment>comment here</comment>
</member>
<member name="banana" color="yellow"/>
</members>
EOS
listener = Listener.new
REXML::Parsers::StreamParser.new(xml, listener).parse
listener.events
# => ["tag_start[members]",
# "text[\n ]",
# "tag_start[member]",
# "text[\n ]",
# "tag_start[comment]",
# "text[comment here]",
# "text[\n ]",
# "text[\n ]",
# "tag_start[member]",
# "text[\n]",
# "text[\n]"]
コールバック仕様確認サンプル
以下の例では様々なXMLの構成要素を含むXML文書を StreamParser で処理したときに、どのコールバックメソッドがどのような引数で呼び出されるかを示すためのサンプルです。実体参照は定義済みのものを除いては変換処理されていないことなどがわかります。
require 'rexml/parsers/baseparser'
require 'rexml/parsers/streamparser'
require 'rexml/streamlistener'
xml = <<EOS
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/css" href="style.css"?>
<!DOCTYPE root SYSTEM "foo" [
<!ELEMENT root (a+)>
<!ELEMENT a>
<!ENTITY bar "barbarbarbar">
<!ATTLIST a att CDATA #REQUIRED xyz CDATA "foobar">
<!NOTATION foobar SYSTEM "http://example.org/foobar.dtd">
<!ENTITY % HTMLsymbol PUBLIC
"-//W3C//ENTITIES Symbols for XHTML//EN"
"xhtml-symbol.ent">
%HTMLsymbol;
]>
<root xmlns:foo="http://example.org/foo"
xmlns:bar="http://example.org/bar"><![CDATA[cdata is here]]>
<a foo:att='1' bar:att='2' att='<'/>
&& <!-- comment here--> &bar;
</root>
EOS
class Listener
def method_missing(name, *args)
p [name, *args]
end
def respond_to_missing?(sym, include_private)
true
end
end
REXML::Parsers::StreamParser.new(xml, Listener.new).parse
# >> [:xmldecl, "1.0", "UTF-8", nil]
# >> [:text, "\n"]
# >> [:instruction, "xml-stylesheet", " type=\"text/css\" href=\"style.css\""]
# >> [:text, "\n"]
# >> [:doctype, "root", "SYSTEM", "foo", nil]
# >> [:elementdecl, "<!ELEMENT root (a+)"]
# >> [:elementdecl, "<!ELEMENT a"]
# >> [:entitydecl, ["bar", "barbarbarbar"]]
# >> [:attlistdecl, "a", {"att"=>nil, "xyz"=>"foobar"}, " \n <!ATTLIST a att CDATA #REQUIRED xyz CDATA \"foobar\">"]
# >> [:notationdecl, ["foobar", "SYSTEM", nil, "http://example.org/foobar.dtd"]]
# >> [:entitydecl, ["HTMLsymbol", "PUBLIC", "-//W3C//ENTITIES Symbols for XHTML//EN", "xhtml-symbol.ent", "%"]]
# >> [:doctype_end]
# >> [:text, "\n"]
# >> [:tag_start, "root", {"xmlns:foo"=>"http://example.org/foo", "xmlns:bar"=>"http://example.org/bar"}]
# >> [:cdata, "cdata is here"]
# >> [:text, "\n "]
# >> [:tag_start, "a", {"foo:att"=>"1", "bar:att"=>"2", "att"=>"<"}]
# >> [:tag_end, "a"]
# >> [:text, "\n && "]
# >> [:comment, " comment here"]
# >> [:text, " &bar;\n"]
# >> [:tag_end, "root"]
# >> [:text, "\n"]
クラス
REXML::Parsers::StreamParser | ストリーム式の XML パーサクラス。 |