class Athena::Formats::XML

Constants

ELEMENT_START_RE

<www.w3.org/TR/2006/REC-xml-20060816/#NT-Name>

NON_ELEMENT_CHAR_RE
VALUE_SEPARATOR

Attributes

specs[R]

Public Instance Methods

convert(record) { |field, struct| ... } click to toggle source
   # File lib/athena/formats/xml.rb
54 def convert(record)
55   builder.row {
56     builder.id record.id
57 
58     record.struct.each { |field, struct|
59       if block_given?
60         yield field, struct
61       else
62         builder.tag!(field) {
63           struct[:elements].each { |element|
64             (struct[:values][element] || []).each { |value|
65               value = (value || '').strip
66               builder.tag!(element, value) unless value.empty?
67             }
68           }
69         }
70       end
71     }
72   }
73 end
parse(input, &block) click to toggle source
   # File lib/athena/formats/xml.rb
49 def parse(input, &block)
50   REXML::Document.parse_stream(input, listener(&block))
51   Athena::Record.records.size
52 end
raw?() click to toggle source
   # File lib/athena/formats/xml.rb
95 def raw?
96   true
97 end

Private Instance Methods

builder(options = {}) click to toggle source
    # File lib/athena/formats/xml.rb
132 def builder(options = {})
133   @builder ||= begin
134     builder = Builder::XmlMarkup.new({ :indent => 2 }.merge(options))
135     builder.instruct!
136 
137     def builder.method_missing(sym, *args, &block)
138       elem = sym.to_s
139 
140       elem.insert(0, '_') unless elem =~ ELEMENT_START_RE
141       elem.gsub!(NON_ELEMENT_CHAR_RE, '_')
142 
143       super(elem, *args, &block)
144     end
145 
146     builder
147   end
148 end
define_spec(element, field, config, arg) click to toggle source
    # File lib/athena/formats/xml.rb
168 def define_spec(element, field, config, arg)
169   spec = ElementSpec.new(element, field, config)
170   arg.is_a?(Hash) ? spec.specs!(arg) : spec.default!(SubElementSpec.new(spec))
171   spec
172 end
init_in(*) click to toggle source
Calls superclass method Athena::Formats::Base#init_in
    # File lib/athena/formats/xml.rb
101 def init_in(*)
102   @__record_element_ok__ = [String, Array]
103   super
104 
105   case @skip_hierarchy = @config.delete(:__skip_hierarchy)
106     when Integer
107       # fine!
108     when nil
109       @skip_hierarchy = 0
110     else
111       raise ConfigError, "illegal value #{@skip_hierarchy.inspect} for skip hierarchy"
112   end
113 
114   @specs = {}
115 
116   @config.each { |element, element_spec| element_spec.each { |field, c|
117     element.split('/').reverse.inject({}) { |hash, part|
118       s = define_spec(element, field, c, hash.empty? ? :default : hash)
119       merge_specs(hash, part, s)
120     }.each { |key, s|
121       merge_specs(@specs, key, s)
122     }
123   } }
124 end
listener(&block) click to toggle source
    # File lib/athena/formats/xml.rb
150 def listener(&block)
151   record_spec = RecordSpec.new(&block)
152   record_spec.specs!(specs)
153 
154   root_spec   = BaseSpec.new
155   [*record_element].each { |re| root_spec.specs!(re => record_spec) }
156 
157   spec        = BaseSpec.new
158   spec.default!(root_spec)
159 
160   @skip_hierarchy.times {
161     prev_spec, spec = spec, BaseSpec.new
162     spec.default!(prev_spec)
163   }
164 
165   XMLStreamin::XMLStreamListener.new(spec)
166 end
merge_specs(container, key, spec) click to toggle source
    # File lib/athena/formats/xml.rb
174 def merge_specs(container, key, spec)
175   container.insert!(key => spec) { |_, spec1, spec2|
176     if spec1.respond_to?(:specs!)
177       spec1.specs!(spec2.respond_to?(:specs) ? spec2.specs : spec2)
178       spec1
179     else
180       spec1.merge(spec2)
181     end
182   }
183 end
wrap() click to toggle source
Calls superclass method Athena::Formats::Base#wrap
    # File lib/athena/formats/xml.rb
126 def wrap
127   res = nil
128   builder(:target => output).database { res = super() }
129   res
130 end