Proper namespace support for attributes.
This separates namespace handling into namespace names and namespace objects. The namespace objects are retrieved from the element an attribute belongs to. Once retrieved the namespace is cached, due to the overhead of retrieving namespaces in large documents.
This commit is contained in:
parent
fe8f77cf45
commit
04cbbdcf9e
|
@ -7,35 +7,44 @@ module Oga
|
|||
# The name of the attribute.
|
||||
# @return [String]
|
||||
#
|
||||
# @!attribute [rw] namespace
|
||||
# The namespace of the attribute.
|
||||
# @return [Oga::XML::Namespace]
|
||||
# @!attribute [rw] namespace_name
|
||||
# @return [String]
|
||||
#
|
||||
# @!attribute [rw] value
|
||||
# The value of the attribute.
|
||||
# @return [String]
|
||||
#
|
||||
# @!attribute [r] element
|
||||
# The element this attribute belongs to.
|
||||
# @return [Oga::XML::Element]
|
||||
#
|
||||
class Attribute
|
||||
attr_accessor :name, :namespace, :value
|
||||
attr_accessor :name, :namespace_name, :element, :value
|
||||
|
||||
##
|
||||
# @param [Hash] options
|
||||
#
|
||||
# @option options [String] :name
|
||||
# @option options [Oga::XML::Namespace] :namespace
|
||||
# @option options [String] :namespace_name
|
||||
# @option options [String] :value
|
||||
# @option options [Oga::XML::Element] :element
|
||||
#
|
||||
def initialize(options = {})
|
||||
if options[:namespace] and !options[:namespace].is_a?(Namespace)
|
||||
raise(
|
||||
TypeError,
|
||||
':namespace must be an instance of Oga::XML::Namespace'
|
||||
)
|
||||
end
|
||||
@name = options[:name]
|
||||
@value = options[:value]
|
||||
@element = options[:element]
|
||||
|
||||
@name = options[:name]
|
||||
@namespace = options[:namespace]
|
||||
@value = options[:value]
|
||||
@namespace_name = options[:namespace_name]
|
||||
end
|
||||
|
||||
##
|
||||
# Returns the {Oga::XML::Namespace} instance for the current namespace
|
||||
# name.
|
||||
#
|
||||
# @return [Oga::XML::Namespace]
|
||||
#
|
||||
def namespace
|
||||
return @namespace ||= element.available_namespaces[namespace_name]
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -4,16 +4,24 @@ module Oga
|
|||
# The Namespace class contains information about XML namespaces such as the
|
||||
# name and URI.
|
||||
#
|
||||
# @!attribute [r] name
|
||||
# @return [String]
|
||||
#
|
||||
# @!attribute [r] uri
|
||||
# @return [String]
|
||||
#
|
||||
class Namespace
|
||||
attr_accessor :name
|
||||
attr_accessor :name, :uri
|
||||
|
||||
##
|
||||
# @param [Hash] options
|
||||
#
|
||||
# @option options [String] :name
|
||||
# @option options [String] :uri
|
||||
#
|
||||
def initialize(options = {})
|
||||
@name = options[:name]
|
||||
@uri = options[:uri]
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -27,7 +35,7 @@ module Oga
|
|||
# @return [String]
|
||||
#
|
||||
def inspect
|
||||
return "Namespace(name: #{name.inspect})"
|
||||
return "Namespace(name: #{name.inspect} uri: #{uri.inspect})"
|
||||
end
|
||||
end # Namespace
|
||||
end # XML
|
||||
|
|
|
@ -150,9 +150,7 @@ rule
|
|||
# foo:bar
|
||||
| T_ATTR_NS T_ATTR
|
||||
{
|
||||
ns = Namespace.new(:name => val[0])
|
||||
|
||||
Attribute.new(:namespace => ns, :name => val[1])
|
||||
Attribute.new(:namespace_name => val[0], :name => val[1])
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -6,24 +6,31 @@ describe Oga::XML::Attribute do
|
|||
described_class.new(:name => 'a').name.should == 'a'
|
||||
end
|
||||
|
||||
example 'set the namespace' do
|
||||
ns = Oga::XML::Namespace.new(:name => 'foo')
|
||||
attr = described_class.new(:namespace => ns)
|
||||
|
||||
attr.namespace.should == ns
|
||||
end
|
||||
|
||||
example 'raise TypeError when using a String for the namespace' do
|
||||
block = lambda { described_class.new(:namespace => 'x') }
|
||||
|
||||
block.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
example 'set the value' do
|
||||
described_class.new(:value => 'a').value.should == 'a'
|
||||
end
|
||||
end
|
||||
|
||||
context '#namespace' do
|
||||
before do
|
||||
@namespace = Oga::XML::Namespace.new(:name => 'b')
|
||||
|
||||
element = Oga::XML::Element.new(
|
||||
:namespaces => {'b' => @namespace}
|
||||
)
|
||||
|
||||
@attribute = described_class.new(
|
||||
:namespace_name => 'b',
|
||||
:name => 'a',
|
||||
:element => element
|
||||
)
|
||||
end
|
||||
|
||||
example 'return a Namespace instance' do
|
||||
@attribute.namespace.should == @namespace
|
||||
end
|
||||
end
|
||||
|
||||
context '#to_s' do
|
||||
example 'return an empty String when there is no value' do
|
||||
described_class.new.to_s.should == ''
|
||||
|
@ -44,14 +51,19 @@ describe Oga::XML::Attribute do
|
|||
|
||||
context '#inspect' do
|
||||
example 'return the inspect value' do
|
||||
element = Oga::XML::Element.new(
|
||||
:namespaces => {'b' => Oga::XML::Namespace.new(:name => 'b')}
|
||||
)
|
||||
|
||||
obj = described_class.new(
|
||||
:name => 'a',
|
||||
:namespace => Oga::XML::Namespace.new(:name => 'b'),
|
||||
:value => 'c'
|
||||
:namespace_name => 'b',
|
||||
:name => 'a',
|
||||
:value => 'c',
|
||||
:element => element
|
||||
)
|
||||
|
||||
obj.inspect.should == <<-EOF.strip
|
||||
Attribute(name: "a" namespace: Namespace(name: "b") value: "c")
|
||||
Attribute(name: "a" namespace: Namespace(name: "b" uri: nil) value: "c")
|
||||
EOF
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue