lib/atom/xml/parser.rb in ratom-0.4.2 vs lib/atom/xml/parser.rb in ratom-0.5.0

- old
+ new

@@ -75,11 +75,11 @@ def parse(xml, options = {}) starting_depth = xml.depth loop do case xml.node_type when XML::Reader::TYPE_ELEMENT - if element_specs.include?(xml.local_name) && [Atom::NAMESPACE, Atom::Pub::NAMESPACE].include?(xml.namespace_uri) + if element_specs.include?(xml.local_name) && (self.class.known_namespaces + [Atom::NAMESPACE, Atom::Pub::NAMESPACE]).include?(xml.namespace_uri) element_specs[xml.local_name].parse(self, xml) elsif attributes.any? while (xml.move_to_next_attribute == 1) if attributes.include?(xml.name) # Support attribute names with namespace prefixes @@ -96,11 +96,13 @@ break unless !options[:once] && xml.next == 1 && xml.depth >= starting_depth end end def next_node_is?(xml, element, ns = nil) - xml.next == 1 && current_node_is?(xml, element, ns) + # Get to the next element + while xml.next == 1 && xml.node_type != XML::Reader::TYPE_ELEMENT; end + current_node_is?(xml, element, ns) end def current_node_is?(xml, element, ns = nil) xml.node_type == XML::Reader::TYPE_ELEMENT && xml.local_name == element && (ns.nil? || ns == xml.namespace_uri) end @@ -112,10 +114,13 @@ def o.attributes; @attributes ||= []; end def element_specs; self.class.element_specs; end def ordered_element_specs; self.class.ordered_element_specs; end def attributes; self.class.attributes; end def o.namespace(ns = @namespace); @namespace = ns; end + def o.add_extension_namespace(ns, url); self.extensions_namespaces[ns.to_s] = url; end + def o.extensions_namespaces; @extensions_namespaces ||= {} end + def o.known_namespaces; @known_namespaces ||= [] end end o.send(:extend, DeclarationMethods) end def ==(o) @@ -136,10 +141,13 @@ # def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil, namespace_map = nil) namespace_map = NamespaceMap.new(self.class.namespace) if namespace_map.nil? node = XML::Node.new(root_name) node['xmlns'] = self.class.namespace unless nodeonly || !self.class.respond_to?(:namespace) + self.class.extensions_namespaces.each do |ns_alias,uri| + node["xmlns:#{ns_alias}"] = uri + end self.class.ordered_element_specs.each do |spec| if spec.single? if attribute = self.send(spec.attribute) if attribute.respond_to?(:to_xml) @@ -208,22 +216,32 @@ def element(*names) options = {:type => :single} options.merge!(names.pop) if names.last.is_a?(Hash) names.each do |name| - attr_accessor name - self.ordered_element_specs << self.element_specs[name.to_s] = ParseSpec.new(name, options) + attr_accessor name.to_s.sub(/:/, '_').to_sym + ns, local_name = name.to_s[/(.*):(.*)/,1], $2 || name + self.known_namespaces << self.extensions_namespaces[ns] if ns + self.ordered_element_specs << self.element_specs[local_name.to_s] = ParseSpec.new(name, options) end end def elements(*names) options = {:type => :collection} options.merge!(names.pop) if names.last.is_a?(Hash) names.each do |name| - attr_accessor name - self.ordered_element_specs << self.element_specs[name.to_s.singularize] = ParseSpec.new(name, options) + name_sym = name.to_s.sub(/:/, '_').to_sym + attr_writer name_sym + define_method name_sym do + ivar = :"@#{name_sym}" + self.instance_variable_set ivar, [] unless self.instance_variable_defined? ivar + self.instance_variable_get ivar + end + ns, local_name = name.to_s[/(.*):(.*)/,1], $2 || name + self.known_namespaces << self.extensions_namespaces[ns] if ns + self.ordered_element_specs << self.element_specs[local_name.to_s.singularize] = ParseSpec.new(name, options) end end def attribute(*names) names.each do |name| @@ -312,10 +330,12 @@ def parse(target, xml) case options[:type] when :single target.send("#{@attribute}=".to_sym, build(target, xml)) when :collection - target.send("#{@attribute}") << build(target, xml) + collection = target.send(@attribute.to_s) + element = build(target, xml) + collection << element end end def single? options[:type] == :single