- # skip the first element, which is our opening element of the block
- @reader.read
- # loop over all elements.
- # NOTE: XML::Reader#read returns 0 for EOF and -1 for error.
- while @reader.read == 1
- break if @reader.node_type == 15 # end element
- next unless @reader.node_type == 1 # element
- yield @reader.name
+ # if the start element is empty then don't do any processing, as
+ # there won't be any child elements to process!
+ unless @reader.empty_element?
+ # read the first element
+ read_or_die
+
+ while @reader.node_type != 15 # end element
+ # because we read elements in DOM-style to reuse their DOM
+ # parsing code, we don't always read an element on each pass
+ # as the call to @reader.next in the innermost loop will take
+ # care of that for us.
+ if @reader.node_type == 1 # element
+ name = @reader.name
+ attributes = {}
+
+ if @reader.has_attributes?
+ while @reader.move_to_next_attribute == 1
+ attributes[@reader.name] = @reader.value
+ end
+
+ @reader.move_to_element
+ end
+
+ yield name, attributes
+ else
+ read_or_die
+ end
+ end