module Rsxml::Sexp
Public Instance Methods
compare(sexpa, sexpb, path=nil)
click to toggle source
# File lib/rsxml/sexp.rb, line 61 def compare(sexpa, sexpb, path=nil) element_name_a, attrsa, childrena = decompose_sexp(sexpa) element_name_b, attrsb, childrenb = decompose_sexp(sexpb) raise ComparisonError.new("element names differ: '#{element_name_a}', '#{element_name_b}'", path) if element_name_a != element_name_b raise ComparisonError.new("attributes differ", path) if attrsa != attrsb raise ComparisonError.new("child count differs", path) if childrena.length != childrenb.length path = [path, element_name_a].compact.join("/") (0...childrena.length).each do |i| if childrena[i].is_a?(Array) && childrenb[i].is_a?(Array) compare(childrena[i], childrenb[i], path) else raise ComparisonError.new("content differs: '#{childrena[i]}', '#{childrenb[i]}'", path) if childrena[i] != childrenb[i] end end true end
decompose_sexp(sexp)
click to toggle source
decompose a sexp to a [element_name, attrs, children] list
# File lib/rsxml/sexp.rb, line 36 def decompose_sexp(sexp) raise "invalid rsxml: #{rsxml.inspect}" if sexp.length<1 if sexp[0].is_a?(Array) element_name = sexp[0] else element_name = sexp[0].to_s end if sexp[1].is_a?(Hash) attrs = sexp[1] children = sexp[2..-1] else attrs = {} children = sexp[1..-1] end [element_name, attrs, children] end
traverse(sexp, visitor, context=Visitor::Context.new)
click to toggle source
pre-order traversal of the sexp, calling methods on the visitor with each node
# File lib/rsxml/sexp.rb, line 8 def traverse(sexp, visitor, context=Visitor::Context.new) element_name, attrs, children = decompose_sexp(sexp) non_ns_attrs, ns_bindings = Namespace::non_ns_attrs_ns_bindings(context.ns_stack, element_name, attrs) context.ns_stack.push(ns_bindings) eelement_name = Namespace::explode_qname(context.ns_stack, element_name) eattrs = Namespace::explode_attr_qnames(context.ns_stack, non_ns_attrs) begin visitor.element(context, eelement_name, eattrs, ns_bindings) do children.each_with_index do |child, i| if child.is_a?(Array) traverse(child, visitor, context) else visitor.text(context, child) end end end ensure context.ns_stack.pop end visitor end