Skip to content

Instantly share code, notes, and snippets.

@dimerman
Forked from dimus/Hash.from_xml using Nokogiri
Created December 12, 2012 21:52

Revisions

  1. @dimus dimus revised this gist Mar 17, 2010. 1 changed file with 18 additions and 10 deletions.
    28 changes: 18 additions & 10 deletions Hash.from_xml using Nokogiri
    Original file line number Diff line number Diff line change
    @@ -4,10 +4,10 @@ require 'nokogiri'

    class Hash
    class << self
    def from_xml(xml_string)
    def from_xml(xml_io)
    begin
    result = Nokogiri::XML.parse(xml_string)
    return { result.root.name.to_s => xml_node_to_hash(result.root)}
    result = Nokogiri::XML(xml_io)
    return { result.root.name.to_sym => xml_node_to_hash(result.root)}
    rescue Exception => e
    # raise your custom exception here
    end
    @@ -20,7 +20,7 @@ class Hash
    if node.attributes != {}
    result_hash[:attributes] = {}
    node.attributes.keys.each do |key|
    result_hash[:attributes][node.attributes[key].name.to_sym] = node.attributes[key].value
    result_hash[:attributes][node.attributes[key].name.to_sym] = prepare(node.attributes[key].value)
    end
    end
    if node.children.size > 0
    @@ -29,28 +29,36 @@ class Hash

    if child.name == "text"
    unless child.next_sibling || child.previous_sibling
    return result
    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] << result
    result_hash[child.name.to_sym] << prepare(result)
    else
    result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << result
    result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << prepare(result)
    end
    else
    result_hash[child.name.to_sym] = result
    result_hash[child.name.to_sym] = prepare(result)
    end
    end

    return result_hash
    else
    puts node.name
    return result_hash
    end
    else
    return node.content.to_s
    return prepare(node.content.to_s)
    end
    end

    def prepare(data)
    (data.class == String && data.to_i.to_s == data) ? data.to_i : data
    end
    end

    def to_struct(struct_name)
    Struct.new(struct_name,*keys).new(*values)
    end
    end


  2. @dimus dimus revised this gist Mar 17, 2010. 1 changed file with 2 additions and 3 deletions.
    5 changes: 2 additions & 3 deletions Hash.from_xml using Nokogiri
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,6 @@
    # USAGE: Hash.from_libxml(YOUR_XML_STRING)
    # USAGE: Hash.from_xml:(YOUR_XML_STRING)
    require 'nokogiri'
    # adapted from
    # http://movesonrails.com/articles/2008/02/25/libxml-for-active-resource-2-0
    # modified from http://stackoverflow.com/questions/1230741/convert-a-nokogiri-document-to-a-ruby-hash/1231297#1231297

    class Hash
    class << self
  3. @dimus dimus created this gist Mar 17, 2010.
    57 changes: 57 additions & 0 deletions Hash.from_xml using Nokogiri
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    # USAGE: Hash.from_libxml(YOUR_XML_STRING)
    require 'nokogiri'
    # adapted from
    # http://movesonrails.com/articles/2008/02/25/libxml-for-active-resource-2-0

    class Hash
    class << self
    def from_xml(xml_string)
    begin
    result = Nokogiri::XML.parse(xml_string)
    return { result.root.name.to_s => xml_node_to_hash(result.root)}
    rescue Exception => e
    # raise your custom exception here
    end
    end

    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] = 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 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] << result
    else
    result_hash[child.name.to_sym] = [result_hash[child.name.to_sym]] << result
    end
    else
    result_hash[child.name.to_sym] = result
    end
    end

    return result_hash
    else
    puts node.name
    return result_hash
    end
    else
    return node.content.to_s
    end
    end
    end
    end