Ensure SAX after_element receives meaningful args

This changes the behaviour of after_element when parsing documents using the SAX
parsing API. Previously it would always receive a nil argument, which is kinda
pointless. This commit changes that by making sure it receives a namespace name
(if any) and the element name.

This fixes #54.
This commit is contained in:
Yorick Peterse committed 2014-11-16 23:32:32 +01:00
1 parent 8c8ecce447
commit 57adabc068
3 files changed
+73 -2

No files matched your search

+55 -1
View File
@@ -37,6 +37,26 @@ module Oga
# For information on the callback arguments see the documentation of the
# corresponding methods in {Oga::XML::Parser}.
#
# ## Element Callbacks
#
# The SAX parser changes the behaviour of both `on_element` and
# `after_element`. The latter in the regular parser only takes a
# {Oga::XML::Element} instance. In the SAX parser it will instead take a
# namespace name and the element name. This eases the process of figuring
# out what element a callback is associated with.
#
# An example:
#
# class SaxHandler
# def on_element(namespace, name, attrs = {})
# # ...
# end
#
# def after_element(namespace, name)
# puts name # => "foo", "bar", etc
# end
# end
#
class SaxParser < Parser
##
# @param [Object] handler The SAX handler to delegate callbacks to.
@@ -52,12 +72,46 @@ module Oga
instance_methods.grep(/^(on_|after_)/).each do |method|
eval <<-EOF, nil, __FILE__, __LINE__ + 1
def #{method}(*args)
@handler.#{method}(*args) if @handler.respond_to?(:#{method})
run_callback(:#{method}, *args)
return
end
EOF
end
##
# Manually overwrite `on_element` so we can ensure that `after_element`
# always receives the namespace and name.
#
# @see [Oga::XML::Parser#on_element]
# @return [Array]
#
def on_element(namespace, name, attrs = {})
run_callback(:on_element, namespace, name, attrs)
return namespace, name
end
##
# Manually overwrite `after_element` so it can take a namespace and name.
# This differs a bit from the regular `after_element` which only takes an
# {Oga::XML::Element} instance.
#
# @param [Array] namespace_with_name
#
def after_element(namespace_with_name)
run_callback(:after_element, *namespace_with_name)
end
private
##
# @param [Symbol] method
# @param [Array] args
#
def run_callback(method, *args)
@handler.send(method, *args) if @handler.respond_to?(method)
end
end # SaxParser
end # XML
end # Oga