lib/atom/xml/parser.rb in ratom-0.3.2 vs lib/atom/xml/parser.rb in ratom-0.3.3
- old
+ new
@@ -29,10 +29,31 @@
end
end
module Atom
module Xml # :nodoc:
+ class NamespaceMap
+ def initialize
+ @i = 0
+ @map = {}
+ end
+
+ def get(ns)
+ if ns == Atom::NAMESPACE
+ @map[ns] = "atom"
+ elsif ns == Atom::Pub::NAMESPACE
+ @map[ns] = "app"
+ else
+ @map[ns] or @map[ns] = "ns#{@i += 1}"
+ end
+ end
+
+ def each(&block)
+ @map.each(&block)
+ end
+ end
+
module Parseable # :nodoc:
def parse(xml, options = {})
starting_depth = xml.depth
loop do
case xml.node_type
@@ -43,10 +64,11 @@
while (xml.move_to_next_attribute == 1)
if attributes.include?(xml.name)
# Support attribute names with namespace prefixes
self.send("#{xml.name.sub(/:/, '_')}=", xml.value)
elsif self.respond_to?(:simple_extensions)
+ self[xml.namespace_uri, xml.local_name].as_attribute = true
self[xml.namespace_uri, xml.local_name] << xml.value
end
end
elsif self.respond_to?(:simple_extensions)
self[xml.namespace_uri, xml.local_name] << xml.read_string
@@ -85,18 +107,19 @@
else
false
end
end
- def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil)
+ def to_xml(nodeonly = false, root_name = self.class.name.demodulize.downcase, namespace = nil, namespace_map = nil)
+ namespace_map = NamespaceMap.new if namespace_map.nil?
node = XML::Node.new(root_name)
node['xmlns'] = self.class.namespace unless nodeonly || !self.class.respond_to?(:namespace)
self.class.element_specs.values.select {|s| s.single? }.each do |spec|
if attribute = self.send(spec.attribute)
if attribute.respond_to?(:to_xml)
- node << attribute.to_xml(true, spec.name, spec.options[:namespace])
+ node << attribute.to_xml(true, spec.name, spec.options[:namespace], namespace_map)
else
n = XML::Node.new(spec.name)
n['xmlns'] = spec.options[:namespace]
n << (attribute.is_a?(Time)? attribute.xmlschema : attribute.to_s)
node << n
@@ -105,11 +128,11 @@
end
self.class.element_specs.values.select {|s| !s.single? }.each do |spec|
self.send(spec.attribute).each do |attribute|
if attribute.respond_to?(:to_xml)
- node << attribute.to_xml(true, spec.name.singularize)
+ node << attribute.to_xml(true, spec.name.singularize, nil, namespace_map)
else
n = XML::Node.new(spec.name.singularize)
n['xmlns'] = spec.options[:namespace]
n << attribute.to_s
node << n
@@ -127,21 +150,28 @@
if self.respond_to?(:simple_extensions) && self.simple_extensions
self.simple_extensions.each do |name, value_array|
if name =~ /\{(.*),(.*)\}/
value_array.each do |value|
- ext = XML::Node.new($2)
- ext['xmlns'] = $1
- ext << value
- node << ext
+ if value_array.as_attribute
+ node["#{namespace_map.get($1)}:#{$2}"] = value
+ else
+ ext = XML::Node.new("#{namespace_map.get($1)}:#{$2}")
+ ext << value
+ node << ext
+ end
end
else
STDERR.print "Couldn't split #{name}"
end
end
end
unless nodeonly
+ namespace_map.each do |ns, prefix|
+ node["xmlns:#{prefix}"] = ns
+ end
+
doc = XML::Document.new
doc.root = node
doc.to_s
else
node