Allow Document#each_node to skip child nodes.

Child nodes can be skipped by throwing :skip_children.
This commit is contained in:
Yorick Peterse 2014-08-04 10:00:32 +02:00
parent ef1ad5406a
commit 57fcbbd0fc
2 changed files with 34 additions and 5 deletions

View File

@ -53,14 +53,25 @@ module Oga
# Traverses through the document and yields every node to the supplied
# block.
#
# The block's body can also determine whether or not to traverse child
# nodes. Preventing a node's children from being traversed can be done by
# using `throw :skip_children`
#
# This method uses a combination of breadth-first and depth-first
# traversal to traverse the entire XML tree in document order. See
# http://en.wikipedia.org/wiki/Breadth-first_search for more information.
#
# @example
# document.each_node do |node|
# p node.class
# end
#
# This method uses a combination of breadth-first and depth-first
# traversal to traverse the entire XML tree in document order. See
# http://en.wikipedia.org/wiki/Breadth-first_search for more information.
# @example Skipping the children of a certain node
# document.each_node do |node|
# if node.is_a?(Oga::XML::Element) and node.name == 'book'
# throw :skip_children
# end
# end
#
# @yieldparam [Oga::XML::Node] The current node.
#
@ -70,9 +81,11 @@ module Oga
until visit.empty?
current = visit.shift
yield current
catch :skip_children do
yield current
visit = current.children.to_a + visit
visit = current.children.to_a + visit
end
end
end

View File

@ -53,6 +53,22 @@ describe Oga::XML::Document do
names.should == %w{books book1 title1 Foo book2 title2 Bar}
end
example 'skip child nodes when skip_children is thrown' do
names = []
@document.each_node do |node|
if node.is_a?(Oga::XML::Element)
if node.name == 'book1'
throw :skip_children
else
names << node.name
end
end
end
names.should == %w{books book2 title2}
end
end
context '#to_xml' do