10281584fc8dc419262cbfe826dd14b49f831b4c
[feedcatcher.git] / vendor / rails / activesupport / lib / active_support / xml_mini / nokogiri.rb
1 require 'nokogiri'
2
3 # = XmlMini Nokogiri implementation
4 module ActiveSupport
5 module XmlMini_Nokogiri #:nodoc:
6 extend self
7
8 # Parse an XML Document string into a simple hash using libxml / nokogiri.
9 # string::
10 # XML Document string to parse
11 def parse(string)
12 if string.blank?
13 {}
14 else
15 doc = Nokogiri::XML(string)
16 raise doc.errors.first if doc.errors.length > 0
17 doc.to_hash
18 end
19 end
20
21 module Conversions
22 module Document
23 def to_hash
24 root.to_hash
25 end
26 end
27
28 module Node
29 CONTENT_ROOT = '__content__'
30
31 # Convert XML document to hash
32 #
33 # hash::
34 # Hash to merge the converted element into.
35 def to_hash(hash = {})
36 hash[name] ||= attributes_as_hash
37
38 walker = lambda { |memo, parent, child, callback|
39 next if child.blank? && 'file' != parent['type']
40
41 if child.text?
42 (memo[CONTENT_ROOT] ||= '') << child.content
43 next
44 end
45
46 name = child.name
47
48 child_hash = child.attributes_as_hash
49 if memo[name]
50 memo[name] = [memo[name]].flatten
51 memo[name] << child_hash
52 else
53 memo[name] = child_hash
54 end
55
56 # Recusively walk children
57 child.children.each { |c|
58 callback.call(child_hash, child, c, callback)
59 }
60 }
61
62 children.each { |c| walker.call(hash[name], self, c, walker) }
63 hash
64 end
65
66 def attributes_as_hash
67 Hash[*(attribute_nodes.map { |node|
68 [node.node_name, node.value]
69 }.flatten)]
70 end
71 end
72 end
73
74 Nokogiri::XML::Document.send(:include, Conversions::Document)
75 Nokogiri::XML::Node.send(:include, Conversions::Node)
76 end
77 end