module Rsxml::Xml

Constants

WRAP_ELEMENT

Public Instance Methods

explode_element(element) click to toggle source

given a Nokogiri::XML::Element in element , produce a [[local_part, prefix, namespace], {[local_part, prefix, namespace]=>value} pair of exploded element name and attributes with exploded names

# File lib/rsxml/xml.rb, line 42
def explode_element(element)
  eelement = explode_node(element)

  eattrs = Hash[element.attributes.map do |name,attr|
                  [explode_node(attr), attr.value]
                end]

  [eelement, eattrs]
end
explode_node(node) click to toggle source
# File lib/rsxml/xml.rb, line 30
def explode_node(node)
  node_name = node.name
  if node.namespace
    node_prefix = node.namespace.prefix || "" # nokogiri has nil prefix for default namespace
    node_uri = node.namespace.href
  end
  node = node_uri ? [node_name, node_prefix, node_uri] : node_name
end
namespace_bindings_from_defs(ns_defs) click to toggle source

give a list of Nokogiri::XML::Namespace definitions, produce a Hash {prefix=>uri} of namespace bindings

# File lib/rsxml/xml.rb, line 54
def namespace_bindings_from_defs(ns_defs)
  (ns_defs||[]).reduce({}) do |h,ns_def|
    h[ns_def.prefix||""] = ns_def.href
    h
  end
end
traverse(element, visitor, context = Visitor::Context.new) click to toggle source

pre-order traversal of the Nokogiri Nodes, calling methods on the visitor with each Node

# File lib/rsxml/xml.rb, line 63
def traverse(element, visitor, context = Visitor::Context.new)
  ns_bindings = namespace_bindings_from_defs(element.namespace_definitions)
  context.ns_stack.push(ns_bindings)

  eelement, eattrs = explode_element(element)

  begin
    visitor.element(context, eelement, eattrs, ns_bindings) do
      element.children.each do |child|
        if child.element?
          traverse(child, visitor, context)
        elsif child.text?
          visitor.text(context, child.content)
        else
          Rsxml.log{|logger| logger.warn("unknown Nokogiri Node type: #{child.inspect}")}
        end
      end
    end
  ensure
    context.ns_stack.pop
  end

  visitor
end
unwrap_fragment(node) click to toggle source
# File lib/rsxml/xml.rb, line 22
def unwrap_fragment(node)
  if node.name==WRAP_ELEMENT
    node.children.first
  else
    node
  end
end
wrap_fragment(fragment, ns_prefixes) click to toggle source
# File lib/rsxml/xml.rb, line 8
def wrap_fragment(fragment, ns_prefixes)
  return fragment if !ns_prefixes

  ns_attrs = Hash[ns_prefixes.map do |prefix,href|
                    prefix = nil if prefix.to_s.length == 0
                    [["xmlns", prefix].compact.join(":"), href]
                  end]
  xml = Builder::XmlMarkup.new
  xml.__send__(WRAP_ELEMENT, ns_attrs) do
    xml << fragment
  end
  xml.target!
end