提交 694998ee 编写于 作者: A Aaron Patterson 提交者: Jeremy Kemper

Nokogiri backend for XmlMini

[#2190 state:committed]
Signed-off-by: NJeremy Kemper <jeremy@bitsweat.net>
上级 d4091d3b
*Edge*
* XmlMini supports libxml if available. #2084 [Bart ten Brinke]
* XmlMini supports LibXML and Nokogiri backends. #2084, #2190 [Bart ten Brinke, Aaron Patterson]
Example: XmlMini.backend = 'Nokogiri'
*2.3.1 [RC2] (March 5, 2009)*
......
......@@ -8,6 +8,10 @@ module XmlMini
extend self
delegate :parse, :to => :@backend
class << self
attr_reader :backend
end
def backend=(name)
require "active_support/xml_mini/#{name.to_s.downcase}.rb"
@backend = ActiveSupport.const_get("XmlMini_#{name}")
......
# = XML Mini Nokogiri implementation
module ActiveSupport
module XmlMini_Nokogiri #:nodoc:
extend self
# Parse an XML Document string into a simple hash using libxml / nokogiri.
# string::
# XML Document string to parse
def parse(string)
return {} if string.blank?
doc = Nokogiri::XML(string).to_hash
end
module Conversions
module Document
def to_hash
root.to_hash
end
end
module Node
CONTENT_ROOT = '__content__'
# Convert XML document to hash
#
# hash::
# Hash to merge the converted element into.
def to_hash(hash = {})
hash[name] ||= attributes_as_hash
walker = lambda { |child, memo, callback|
next if child.blank?
if child.text?
(memo[CONTENT_ROOT] ||= '') << child.content
next
end
name = child.name
if memo[name]
memo[name] = [memo[name]].flatten
memo[name] << child.attributes_as_hash
else
memo[name] = child.attributes_as_hash
end
# Recusively walk children
child.children.each { |c| callback.call(c, memo[name], callback) }
}
children.each { |c| walker.call(c, hash[name], walker) }
hash
end
def attributes_as_hash
Hash[*(attribute_nodes.map { |node|
[node.node_name, node.value]
}.flatten)]
end
end
end
Nokogiri::XML::Document.send(:include, Conversions::Document)
Nokogiri::XML::Node.send(:include, Conversions::Node)
end
end
require 'abstract_unit'
require 'active_support/xml_mini'
begin
require 'nokogiri'
class NokogiriEngineTest < Test::Unit::TestCase
include ActiveSupport
def setup
@default_backend = XmlMini.backend.to_s.split('_').last
XmlMini.backend = 'Nokogiri'
end
def teardown
XmlMini.backend = @default_backend
end
def test_setting_nokogiri_as_backend
XmlMini.backend = 'Nokogiri'
assert_equal XmlMini_Nokogiri, XmlMini.backend
end
def test_blank_returns_empty_hash
assert_equal({}, XmlMini.parse(nil))
assert_equal({}, XmlMini.parse(''))
end
def test_one_node_document_as_hash
assert_equal_rexml(<<-eoxml)
<products/>
eoxml
end
def test_one_node_with_attributes_document_as_hash
assert_equal_rexml(<<-eoxml)
<products foo="bar"/>
eoxml
end
def test_products_node_with_book_node_as_hash
assert_equal_rexml(<<-eoxml)
<products>
<book name="awesome" id="12345" />
</products>
eoxml
end
def test_products_node_with_two_book_nodes_as_hash
assert_equal_rexml(<<-eoxml)
<products>
<book name="awesome" id="12345" />
<book name="america" id="67890" />
</products>
eoxml
end
def test_single_node_with_content_as_hash
assert_equal_rexml(<<-eoxml)
<products>
hello world
</products>
eoxml
end
def test_children_with_children
assert_equal_rexml(<<-eoxml)
<root>
<products>
<book name="america" id="67890" />
</products>
</root>
eoxml
end
def test_children_with_text
assert_equal_rexml(<<-eoxml)
<root>
<products>
hello everyone
</products>
</root>
eoxml
end
def test_children_with_non_adjacent_text
assert_equal_rexml(<<-eoxml)
<root>
good
<products>
hello everyone
</products>
morning
</root>
eoxml
end
private
def assert_equal_rexml(xml)
XmlMini.backend = 'REXML'
hash = XmlMini.parse(xml)
XmlMini.backend = 'Nokogiri'
assert_equal(hash, XmlMini.parse(xml))
end
end
rescue LoadError
# Yay, no errors
end
require 'abstract_unit'
require 'active_support/xml_mini'
class REXMLEngineTest < Test::Unit::TestCase
include ActiveSupport
def test_default_is_rexml
assert_equal XmlMini_REXML, XmlMini.backend
end
def test_set_rexml_as_backend
XmlMini.backend = 'REXML'
assert_equal XmlMini_REXML, XmlMini.backend
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册