ストリーム式の XML パーサ。
rexml の XML パーサの中では高速ですが、機能は限定的です。もう少し高機能なストリーム式パーサが必要な場合は REXML::Parsers::SAX2Parser を用いてください。
パーサからはコールバックによってパースした情報を受け取ります。 REXML::StreamListener を include し、必要なメソッドをオーバーライドしたクラスのオブジェクトをコールバックオブジェクトとして REXML::Parsers::StreamParser.new に渡します。
REXML::Parsers::StreamParser#parse を呼び出すとパースが開始しその結果によってコールバックが呼び出されます。
コールバックされるメソッドは REXML::StreamListener になにもしないメソッドとして定義されています。どのようなコールバックがあるかはそちらを参照してください。
パーサはXML文書の各構成要素を前から順に処理し、その順にコールバックメソッドを呼び出します。順が前後することはありません。
この例では 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 パーサクラス。 |