1 # = XmlMini ReXML implementation
3 module XmlMini_REXML
#:nodoc:
6 CONTENT_KEY
= '__content__'.freeze
8 # Parse an XML Document string into a simple hash
10 # Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
11 # and uses the defaults from ActiveSupport
14 # XML Document string to parse
16 require 'rexml/document' unless defined?(REXML
::Document)
17 doc
= REXML
::Document.new(string
)
18 merge_element
!({}, doc
.root
)
22 # Convert an XML element and merge into the hash
25 # Hash to merge the converted element into.
27 # XML element to merge into hash
28 def merge_element
!(hash
, element
)
29 merge
!(hash
, element
.name
, collapse(element
))
32 # Actually converts an XML document element into a data structure.
35 # The document element to be collapsed.
37 hash
= get_attributes(element
)
39 if element
.has_elements
?
40 element
.each_element
{|child
| merge_element
!(hash
, child
) }
41 merge_texts
!(hash
, element
) unless empty_content
?(element
)
44 merge_texts
!(hash
, element
)
48 # Merge all the texts of an element into the hash
51 # Hash to add the converted emement to.
53 # XML element whose texts are to me merged into the hash
54 def merge_texts
!(hash
, element
)
55 unless element
.has_text
?
58 # must use value to prevent double-escaping
59 merge
!(hash
, CONTENT_KEY
, element
.texts
.sum(&:value))
63 # Adds a new key/value pair to an existing Hash. If the key to be added
64 # already exists and the existing value associated with key is not
65 # an Array, it will be wrapped in an Array. Then the new value is
66 # appended to that Array.
69 # Hash to add key/value pair to.
73 # Value to be associated with key.
74 def merge
!(hash
, key
, value
)
76 if hash
[key
].instance_of
?(Array
)
79 hash
[key
] = [hash
[key
], value
]
81 elsif value
.instance_of
?(Array
)
89 # Converts the attributes array of an XML element into a hash.
90 # Returns an empty Hash if node has no attributes.
93 # XML element to extract attributes from.
94 def get_attributes(element
)
96 element
.attributes
.each
{ |n
,v
| attributes
[n
] = v
}
100 # Determines if a document element has text content
103 # XML element to be checked.
104 def empty_content
?(element
)
105 element
.texts
.join
.blank
?