Basic work for supporting namespace URIs.

This commit is contained in:
Yorick Peterse 2014-08-08 19:03:42 +02:00
parent f002061aaa
commit fe8f77cf45
5 changed files with 121 additions and 23 deletions

View File

@ -145,6 +145,27 @@ module Oga
return :element return :element
end end
##
# Returns a node set of all the namespaces that are available to the
# current node. This includes the namespaces registered on the current
# node.
#
# @return [Oga::XML::NodeSet]
#
def available_namespaces
end
##
# Returns a node set of all the namespaces registered with the current
# node.
#
# @return [Oga::XML::NodeSet]
#
def namespaces
end
private private
## ##

View File

@ -398,6 +398,24 @@ module Oga
return nodes return nodes
end end
##
# Evaluates the `namespace` axis.
#
# @param [Oga::XPath::Node] ast_node
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_axis_namespace(ast_node, context)
nodes = XML::NodeSet.new
name = ast_node.children[1]
context.each do |context_node|
end
return nodes
end
## ##
# Returns a node set containing all the child nodes of the given set of # Returns a node set containing all the child nodes of the given set of
# nodes. # nodes.
@ -431,15 +449,13 @@ module Oga
# @return [Oga::XML::NodeSet] # @return [Oga::XML::NodeSet]
# #
def node_matches?(xml_node, ast_node) def node_matches?(xml_node, ast_node)
return false unless can_match_node?(xml_node)
ns, name = *ast_node ns, name = *ast_node
name_matches = xml_node.name == name || name == '*' name_matches = name_matches?(xml_node, name)
ns_matches = false ns_matches = false
if ns if ns
ns_matches = xml_node.namespace.to_s == ns || ns == '*' ns_matches = namespace_matches?(xml_node, ns)
# If there's no namespace given but the name matches we'll also mark # If there's no namespace given but the name matches we'll also mark
# the namespace as matching. # the namespace as matching.
@ -454,13 +470,29 @@ module Oga
end end
## ##
# Returns `true` if the given XML node can be compared using # Returns `true` if the name of the XML node matches the given name *or*
# {#node_matches?}. # matches a wildcard.
# #
# @param [Oga::XML::Node] ast_node # @param [Oga::XML::Node] xml_node
# @param [String] name
# #
def can_match_node?(ast_node) def name_matches?(xml_node, name)
return ast_node.respond_to?(:name) && ast_node.respond_to?(:namespace) return false unless xml_node.respond_to?(:name)
return xml_node.name == name || name == '*'
end
##
# Returns `true` if the namespace of the XML node matches the given
# namespace *or* matches a wildcard.
#
# @param [Oga::XML::Node] xml_node
# @param [String] ns
#
def namespace_matches?(xml_node, ns)
return false unless xml_node.respond_to?(:namespace)
return xml_node.namespace.to_s == ns || ns == '*'
end end
## ##

View File

@ -177,4 +177,8 @@ describe Oga::XML::Element do
described_class.new.node_type.should == :element described_class.new.node_type.should == :element
end end
end end
context '#available_namespaces' do
# TODO: write me
end
end end

View File

@ -0,0 +1,55 @@
require 'spec_helper'
describe Oga::XPath::Evaluator do
context 'namespace axis' do
before do
@document = parse(<<-EOF.strip)
<root xmlns:x="x">
<foo xmlns:y="y"></foo>
</root>
EOF
@evaluator = described_class.new(@document)
end
context 'matching namespaces in the root element' do
before do
@set = @evaluator.evaluate('root/namespace::x')
end
it_behaves_like :node_set, :length => 1
example 'return a Namespace instance' do
@set[0].is_a?(Oga::XML::Namespace).should == true
end
example 'return the "x" namespace' do
@set[0].name.should == 'x'
end
end
context 'matching namespaces in a nested element' do
before do
@set = @evaluator.evaluate('root/namespace::x')
end
it_behaves_like :node_set, :length => 2
example 'return the "x" namespace' do
@set[0].name.should == 'x'
end
example 'return the "y" namespace' do
@set[1].name.should == 'y'
end
end
context 'matching namespace nodes using a wildcard' do
before do
@set = @evaluator.evaluate('root/namespace::*')
end
it_behaves_like :node_set, :length => 1
end
end
end

View File

@ -71,20 +71,6 @@ describe Oga::XPath::Evaluator do
end end
end end
context '#can_match_node?' do
example 'return true for an XML::Element instance' do
@evaluator.can_match_node?(Oga::XML::Element.new).should == true
end
example 'return true for an XML::Attribute instance' do
@evaluator.can_match_node?(Oga::XML::Attribute.new).should == true
end
example 'return false for an XML::Text instance' do
@evaluator.can_match_node?(Oga::XML::Text.new).should == false
end
end
context '#has_parent?' do context '#has_parent?' do
before do before do
@parent = Oga::XML::Element.new @parent = Oga::XML::Element.new