REXML と Libxml-Ruby とのエンティティ出力比較
REXML で大きな XML ファイルを処理したらあまりにも遅かった。Ruby で書かれているのでいたし方ないんですが。もちろん REXML は標準でついているし、手軽に使えて良いという大きなメリットがあるけど、行う処理が数時間レベルなので速くしたい。そこで Libxml http://libxml.rubyforge.org/ を試すことに。
行うのは XML → XML 変換なので、エンティティの出力が気になった。そこで次のようなコードを実行して、結果を比較してみる。
テストしたコード
#!/usr/bin/env ruby # require 'rubygems' require 'xml/libxml' require 'rexml/document' str =<<EOS <?xml version="1.0" encoding="UTF-8"?> <root> <title>Tosshi's メモ書き</title> <array> <item attr='''> <html> 'TAG" </item> <item attr="""><![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]></item> </array> </root> EOS puts <<EOS [ libxml-ruby ] EOS xp = XML::Parser.new xp.string = str libxmldoc = xp.parse puts "document :" puts libxmldoc node = libxmldoc.root.find_first("title") print "Node :" puts node print "content :" puts node.content print "child.to_s:" puts node.child.to_s libxmldoc.root.find("array/item").each do |item| print "Node :" puts item print "content :" puts item.content print "child.to_s:" puts item.child.to_s end puts <<EOS [ REXML ] EOS rexmldoc = REXML::Document.new(str) puts "Document :" puts rexmldoc el = rexmldoc.root.elements["title"] print "Element :" puts el print "text :" puts el.text print "get_text :" puts el.get_text rexmldoc.root.elements.each("array/item") do |item| print "Element :" puts item print "text :" puts item.text print "get_text :" puts item.get_text end
結果
- libxml はアポストロフィとダブルクォートを必要なときだけ実体名にエスケープする。
- REXML は属性値は固定でアポストロフィで囲い、アポストロフィとダブルクォートは必ず実体名にエスケープする。
$ ruby testxml.rb [ libxml-ruby ] Document : <?xml version="1.0" encoding="UTF-8"?> <root> <title>Tosshi's メモ書き</title> <array> <item attr="'"> <html> 'TAG" </item> <item attr="""><![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]></item> </array> </root> Node :<title>Tosshi's メモ書き</title> content :Tosshi's メモ書き child.to_s:Tosshi's メモ書き Node :<item attr="'"> <html> 'TAG" </item> content : <html> 'TAG" child.to_s: <html> 'TAG" Node :<item attr="""><![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]></item> content : CDATA <html> 'TAG&qout; <>"' child.to_s:<![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]> [ REXML ] Document : <?xml version='1.0' encoding='UTF-8'?> <root> <title>Tosshi's メモ書き</title> <array> <item attr='''> <html> 'TAG" </item> <item attr='"'><![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]></item> </array> </root> Element :<title>Tosshi's メモ書き</title> text :Tosshi's メモ書き get_text :Tosshi's メモ書き Element :<item attr='''> <html> 'TAG" </item> text : <html> 'TAG" get_text : <html> 'TAG" Element :<item attr='"'><![CDATA[ CDATA <html> 'TAG&qout; <>"' ]]></item> text : CDATA <html> 'TAG&qout; <>"' get_text : CDATA <html> 'TAG&qout; <>"'