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