# File lib/athena/formats/xml.rb, line 54 def convert(record) builder.row { builder.id record.id record.struct.each { |field, struct| if block_given? yield field, struct else builder.tag!(field) { struct[:elements].each { |element| (struct[:values][element] || []).each { |value| value = (value || '').strip builder.tag!(element, value) unless value.empty? } } } end } } end
# File lib/athena/formats/xml.rb, line 49 def parse(input, &block) REXML::Document.parse_stream(input, listener(&block)) Athena::Record.records.size end
# File lib/athena/formats/xml.rb, line 95 def raw? true end
# File lib/athena/formats/xml.rb, line 132 def builder(options = {}) @builder ||= begin builder = Builder::XmlMarkup.new({ :indent => 2 }.merge(options)) builder.instruct! def builder.method_missing(sym, *args, &block) elem = sym.to_s elem.insert(0, '_') unless elem =~ ELEMENT_START_RE elem.gsub!(NON_ELEMENT_CHAR_RE, '_') super(elem, *args, &block) end builder end end
# File lib/athena/formats/xml.rb, line 168 def define_spec(element, field, config, arg) spec = ElementSpec.new(element, field, config) arg.is_a?(Hash) ? spec.specs!(arg) : spec.default!(SubElementSpec.new(spec)) spec end
# File lib/athena/formats/xml.rb, line 101 def init_in(*) @__record_element_ok__ = [String, Array] super case @skip_hierarchy = @config.delete(:__skip_hierarchy) when Integer # fine! when nil @skip_hierarchy = 0 else raise ConfigError, "illegal value #{@skip_hierarchy.inspect} for skip hierarchy" end @specs = {} @config.each { |element, element_spec| element_spec.each { |field, c| element.split('/').reverse.inject({}) { |hash, part| s = define_spec(element, field, c, hash.empty? ? :default : hash) merge_specs(hash, part, s) }.each { |key, s| merge_specs(@specs, key, s) } } } end
# File lib/athena/formats/xml.rb, line 150 def listener(&block) record_spec = RecordSpec.new(&block) record_spec.specs!(specs) root_spec = BaseSpec.new [*record_element].each { |re| root_spec.specs!(re => record_spec) } spec = BaseSpec.new spec.default!(root_spec) @skip_hierarchy.times { prev_spec, spec = spec, BaseSpec.new spec.default!(prev_spec) } XMLStreamin::XMLStreamListener.new(spec) end
# File lib/athena/formats/xml.rb, line 174 def merge_specs(container, key, spec) container.insert!(key => spec) { |_, spec1, spec2| if spec1.respond_to?(:specs!) spec1.specs!(spec2.respond_to?(:specs) ? spec2.specs : spec2) spec1 else spec1.merge(spec2) end } end
# File lib/athena/formats/xml.rb, line 126 def wrap res = nil builder(:target => output).database { res = super() } res end