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