~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/xml_mini/rexml.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# = XmlMini ReXML implementation
2
 
module ActiveSupport
3
 
  module XmlMini_REXML #:nodoc:
4
 
    extend self
5
 
 
6
 
    CONTENT_KEY = '__content__'.freeze
7
 
 
8
 
    # Parse an XML Document string into a simple hash
9
 
    #
10
 
    # Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
11
 
    # and uses the defaults from ActiveSupport
12
 
    #
13
 
    # string::
14
 
    #   XML Document string to parse
15
 
    def parse(string)
16
 
      require 'rexml/document' unless defined?(REXML::Document)
17
 
      doc = REXML::Document.new(string)
18
 
      merge_element!({}, doc.root)
19
 
    end
20
 
 
21
 
    private
22
 
      # Convert an XML element and merge into the hash
23
 
      #
24
 
      # hash::
25
 
      #   Hash to merge the converted element into.
26
 
      # element::
27
 
      #   XML element to merge into hash
28
 
      def merge_element!(hash, element)
29
 
        merge!(hash, element.name, collapse(element))
30
 
      end
31
 
 
32
 
      # Actually converts an XML document element into a data structure.
33
 
      #
34
 
      # element::
35
 
      #   The document element to be collapsed.
36
 
      def collapse(element)
37
 
        hash = get_attributes(element)
38
 
 
39
 
        if element.has_elements?
40
 
          element.each_element {|child| merge_element!(hash, child) }
41
 
          merge_texts!(hash, element) unless empty_content?(element)
42
 
          hash
43
 
        else
44
 
          merge_texts!(hash, element)
45
 
        end
46
 
      end
47
 
 
48
 
      # Merge all the texts of an element into the hash
49
 
      #
50
 
      # hash::
51
 
      #   Hash to add the converted emement to.
52
 
      # element::
53
 
      #   XML element whose texts are to me merged into the hash
54
 
      def merge_texts!(hash, element)
55
 
        unless element.has_text?
56
 
          hash
57
 
        else
58
 
          # must use value to prevent double-escaping
59
 
          merge!(hash, CONTENT_KEY, element.texts.sum(&:value))
60
 
        end
61
 
      end
62
 
 
63
 
      # Adds a new key/value pair to an existing Hash. If the key to be added
64
 
      # already exists and the existing value associated with key is not
65
 
      # an Array, it will be wrapped in an Array. Then the new value is
66
 
      # appended to that Array.
67
 
      #
68
 
      # hash::
69
 
      #   Hash to add key/value pair to.
70
 
      # key::
71
 
      #   Key to be added.
72
 
      # value::
73
 
      #   Value to be associated with key.
74
 
      def merge!(hash, key, value)
75
 
        if hash.has_key?(key)
76
 
          if hash[key].instance_of?(Array)
77
 
            hash[key] << value
78
 
          else
79
 
            hash[key] = [hash[key], value]
80
 
          end
81
 
        elsif value.instance_of?(Array)
82
 
          hash[key] = [value]
83
 
        else
84
 
          hash[key] = value
85
 
        end
86
 
        hash
87
 
      end
88
 
 
89
 
      # Converts the attributes array of an XML element into a hash.
90
 
      # Returns an empty Hash if node has no attributes.
91
 
      #
92
 
      # element::
93
 
      #   XML element to extract attributes from.
94
 
      def get_attributes(element)
95
 
        attributes = {}
96
 
        element.attributes.each { |n,v| attributes[n] = v }
97
 
        attributes
98
 
      end
99
 
 
100
 
      # Determines if a document element has text content
101
 
      #
102
 
      # element::
103
 
      #   XML element to be checked.
104
 
      def empty_content?(element)
105
 
        element.texts.join.blank?
106
 
      end
107
 
  end
108
 
end