lib/dwc-archive/xml_reader.rb in dwc-archive-0.9.10 vs lib/dwc-archive/xml_reader.rb in dwc-archive-0.9.11
- old
+ new
@@ -1,64 +1,80 @@
# USAGE: Hash.from_xml:(YOUR_XML_STRING)
-require 'nokogiri'
# modified from
# http://stackoverflow.com/questions/1230741/
# convert-a-nokogiri-document-to-a-ruby-hash/1231297#1231297
class DarwinCore
module XmlReader
class << self
+
def from_xml(xml_io)
result = Nokogiri::XML(xml_io)
return { result.root.name.to_sym => xml_node_to_hash(result.root)}
end
private
-
def xml_node_to_hash(node)
# If we are at the root of the document, start the hash
if node.element?
- result_hash = {}
- if node.attributes != {}
- result_hash[:attributes] = {}
- node.attributes.keys.each do |key|
- result_hash[:attributes][node.attributes[key].
- name.to_sym] = prepare(node.attributes[key].value)
- end
- end
- if node.children.size > 0
- node.children.each do |child|
- result = xml_node_to_hash(child)
-
- if child.name == "text"
- unless child.next_sibling || child.previous_sibling
- return prepare(result)
- end
- elsif result_hash[child.name.to_sym]
- if result_hash[child.name.to_sym].is_a?(Object::Array)
- result_hash[child.name.to_sym] << prepare(result)
- else
- result_hash[child.name.to_sym] =
- [result_hash[child.name.to_sym]] << prepare(result)
- end
- else
- result_hash[child.name.to_sym] = prepare(result)
- end
- end
-
- return result_hash
- else
- return result_hash
- end
+ prepare_node_element(node)
else
return prepare(node.content.to_s)
end
end
+
+ def add_attributes(node, result_hash)
+ if node.attributes != {}
+ result_hash[:attributes] = {}
+ node.attributes.keys.each do |key|
+ result_hash[:attributes][node.attributes[key].name.to_sym] =
+ prepare(node.attributes[key].value)
+ end
+ end
+ end
+ def prepare_node_element(node)
+ result_hash = {}
+ add_attributes(node, result_hash)
+ if node.children.size > 0
+ result_hash = add_children(node, result_hash)
+ end
+ result_hash
+ end
+
+ def add_children(node, result_hash)
+ node.children.each do |child|
+ result = xml_node_to_hash(child)
+
+ if child.name == "text"
+ text = handle_text(child, result)
+ return text if text
+ elsif result_hash[child.name.to_sym]
+ handle_child_node(child, result_hash, result)
+ else
+ result_hash[child.name.to_sym] = prepare(result)
+ end
+ end
+ result_hash
+ end
+
+ def handle_child_node(child, result_hash, result)
+ if result_hash[child.name.to_sym].is_a?(Object::Array)
+ result_hash[child.name.to_sym] << prepare(result)
+ else
+ result_hash[child.name.to_sym] =
+ [result_hash[child.name.to_sym]] << prepare(result)
+ end
+ end
+
+ def handle_text(child, result)
+ unless child.next_sibling || child.previous_sibling
+ prepare(result)
+ end
+ end
+
def prepare(data)
- return data if data.class != String
- return true if data.strip == "true"
- return false if data.strip == "false"
- data.to_i.to_s == data ? data.to_i : data
+ (data.class == String && data.to_i.to_s == data) ? data.to_i : data
end
+
end
end
end