Skip to content

Instantly share code, notes, and snippets.

@tmd45
Forked from EmmanuelOga/nokogiri.to_hash.rb
Last active January 2, 2016 16:39
Show Gist options
  • Save tmd45/8331561 to your computer and use it in GitHub Desktop.
Save tmd45/8331561 to your computer and use it in GitHub Desktop.
module NokogiriUtils
extend self
# http://gist.github.com/370755
def hash_from_node(node)
{ node.root.name.to_sym => xml_node_to_hash(node.root) }
end
def xml_node_to_hash(node)
return to_value(node.content.to_s) unless node.element?
result_hash = {}
node.attributes.each do |key, attr|
( result_hash[:attributes] ||= Hash.new )[attr.name.to_sym] = to_value(attr.value)
end
node.children.each do |child|
result = xml_node_to_hash(child)
if child.name == "text"
if result_hash[:attributes]
result_hash[:self] = result
return result_hash
else
return result
end
else
key, val = child.name.to_sym, to_value(result)
result_hash[key] = result_hash.key?(key) ? Array(result_hash[key]).push(val) : val
end
end
result_hash
end
def to_value(data)
data.is_a?(String) && data =~ /^\d+$/ ? data.to_i : data
end
end
@tmd45
Copy link
Author

tmd45 commented Jan 9, 2014

fork元のfork元(元ネタ)のほうに入ってたツッコミを反映してみた。
https://gist.github.com/dimus/335286/#comment-366958

i had to modify to pick up attributes for elements that contained only text and attributes
<foo a="one" b="two">some text</foo>

<                 return prepare(result)
---
                if result_hash[:attributes]
                  result_hash['value'] = prepare(result)
                  return result_hash
                else 
                  return prepare(result)
                end 

固定化するkeyの値は 'value' ではなく :self とした。

@tmd45
Copy link
Author

tmd45 commented Jan 9, 2014

to_valueいらんなぁとか思ってたり。。。

@tmd45
Copy link
Author

tmd45 commented Jan 20, 2014

属性付きの要素が配列化されるときにおかしくなる。

<member>
  <likes>
    <programing>Ruby</programing>
    <programing>JavaScript</programing>
  </likes>
  <likes>
    <book isbn="321">たのしい Ruby</book>
    <book isbn="654">JavaScript 入門</book>
  </likes>
</member>

の結果が:

{
  member: {
    likes: [
      [ programing, ["Ruby", "JavaScript"] ],
      {
        book: [
          [ :attributes, { isbn: "321" } ],
          [ :self, "たのしい Ruby" ],
          {
            attributes: { isbn: "654" },
            self: "JavaScript 入門"
          }
        ]
      }
    ]
  }
}

うむぅ。これはひどい。

@tmd45
Copy link
Author

tmd45 commented Jan 20, 2014

ふぁぁー 👎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment