Module: Rsxml::Sexp
- Defined in:
- lib/rsxml/sexp.rb
Defined Under Namespace
Classes: ComparisonError
Class Method Summary collapse
- .compare(sexpa, sexpb, path = nil) ⇒ Object
-
.decompose_sexp(sexp) ⇒ Object
decompose a sexp to a [tag, attrs, children] list.
-
.traverse(sexp, visitor, context = Visitor::Context.new) ⇒ Object
pre-order traversal of the sexp, calling methods on the visitor with each node.
Class Method Details
.compare(sexpa, sexpb, path = nil) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/rsxml/sexp.rb', line 70 def compare(sexpa, sexpb, path=nil) taga, attrsa, childrena = decompose_sexp(sexpa) tagb, attrsb, childrenb = decompose_sexp(sexpb) raise ComparisonError.new("element names differ: '#{taga}', '#{tagb}'", path) if taga != tagb raise ComparisonError.new("attributes differ", path) if attrsa != attrsb raise ComparisonError.new("child count differs", path) if childrena.length != childrenb.length path = [path, taga].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) ⇒ Object
decompose a sexp to a [tag, attrs, children] list
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/rsxml/sexp.rb', line 45 def decompose_sexp(sexp) raise "invalid rsxml: #{rsxml.inspect}" if sexp.length<1 if sexp[0].is_a?(Array) tag = sexp[0] else tag = 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 [tag, attrs, children] end |
.traverse(sexp, visitor, context = Visitor::Context.new) ⇒ Object
pre-order traversal of the sexp, calling methods on the visitor with each node
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/rsxml/sexp.rb', line 8 def traverse(sexp, visitor, context=Visitor::Context.new) tag, attrs, children = decompose_sexp(sexp) ns_bindings, ns_additional_decls = Namespace::namespace_bindings_declarations(context.ns_stack, tag, attrs) context.ns_stack.push(ns_bindings) etag = Namespace::explode_qname(context.ns_stack, tag) eattrs = Namespace::explode_attr_qnames(context.ns_stack, attrs) eattrs = eattrs.merge(ns_additional_decls) begin visitor.tag(context, etag, eattrs) do context.push_node([etag, eattrs]) begin children.each_with_index do |child, i| if child.is_a?(Array) traverse(child, visitor, context) else visitor.text(context, child) context.processed_node(child) end end ensure context.pop_node end end ensure context.ns_stack.pop end visitor end |