class XMLable::Exports::XMLExporter

XMLExporter class exports the data into XML format

Public Class Methods

new(*) click to toggle source

@see XMLable::Exports::Base#initialize

Calls superclass method XMLable::Exports::Base::new
# File lib/xmlable/exports/xml_exporter.rb, line 10
def initialize(*)
  super
  @node = @element.__node
  @document = @node.document? ? @node : @node.document
end

Public Instance Methods

export() click to toggle source

Export the data into XML format

@return [String]

# File lib/xmlable/exports/xml_exporter.rb, line 21
def export
  opts = node_nested_options(@element.__node)
  builder.tap { |b| export_node(@element.__node, opts.merge(xml: b)) }
end

Private Instance Methods

builder() click to toggle source

XML builder

@return [Nokogiri::XML:::Builder]

# File lib/xmlable/exports/xml_exporter.rb, line 33
def builder
  opts = {}
  opts[:encoding] = @document.encoding if @document.encoding
  ::Nokogiri::XML::Builder.new(opts)
end
element_args(node, opts) click to toggle source

Get XML element's attributes and namespace definitions

@param [Nokogiri::XML::Element] node @param [XMLable::Options::Storage] opts

@return [Hash{String => String}]

# File lib/xmlable/exports/xml_exporter.rb, line 118
def element_args(node, opts)
  node_namespaces(node, opts).merge(node_attributes(node, opts))
end
export_document(doc, opts) click to toggle source

Export XML document

@param [Nokogiri::XML::Document] doc @param [XMLable::Options::Storage] opts

# File lib/xmlable/exports/xml_exporter.rb, line 84
def export_document(doc, opts)
  export_node(doc.root, opts)
end
export_element(node, opts) click to toggle source

Export XML element

@param [Nokogiri::XML::Element] node @param [XMLable::Options::Storage] opts

# File lib/xmlable/exports/xml_exporter.rb, line 94
def export_element(node, opts)
  opts = node_merged_opts(node, opts)
  ns = node.namespace
  if ns && !node_ns_definition(node, ns.prefix)
    opts[:xml] = opts[:xml][ns.prefix] if ns.prefix
  end
  opts[:xml].send("#{node.name}_", element_args(node, opts)) do |xml|
    if ns && node_ns_definition(node, ns)
      xml.parent.namespace = node_ns_definition(xml.parent, ns.prefix)
    end
    if !opts.drop_empty_elements? || !empty?(node)
      export_node_children(node, opts.merge(xml: xml))
    end
  end
end
export_node(node, opts) click to toggle source

Export XML node

@param [Nokogiri::XML::Node] node @param [XMLable::Options::Storage] opts

# File lib/xmlable/exports/xml_exporter.rb, line 169
def export_node(node, opts)
  case node
  when Nokogiri::XML::Document then export_document(node, opts)
  when Nokogiri::XML::Element  then export_element(node, opts)
  when Nokogiri::XML::Text     then export_text(node, opts)
  else fail "Don't know how to export node: #{node}"
  end
end
export_node_children(node, opts) click to toggle source

Export nodes' children

@param [Nokogiri::XML::Element] node @param [XMLable::Options::Storage] opts

# File lib/xmlable/exports/xml_exporter.rb, line 142
def export_node_children(node, opts)
  node.children.each do |child|
    next if child.is_a?(Nokogiri::XML::Attr)
    if child.is_a?(Nokogiri::XML::Element)
      next if opts.drop_empty_elements? && empty?(child)
      next if opts.drop_undescribed_elements? && !described?(child)
    end
    export_node(child, opts)
  end
end
export_text(node, opts) click to toggle source

Export XML text node

@param [Nokogiri::XML::Text] node @param [XMLable::Options::Storage] opts

# File lib/xmlable/exports/xml_exporter.rb, line 159
def export_text(node, opts)
  opts[:xml].text(node.text)
end
node_attributes(node, opts) click to toggle source

Get element's attributes

@param [Nokogiri::XML::Element] node XML element @param [XMLable::Options::Storage] opts

@return [Hash{String => String}]

# File lib/xmlable/exports/xml_exporter.rb, line 47
def node_attributes(node, opts)
  return {} unless node.respond_to?(:attributes)
  attrs = node.attributes.values.select do |att|
    next if opts.drop_undescribed_attributes? && !described?(att)
    next if opts.drop_empty_attributes? && empty?(att)
    true
  end
  attrs.each_with_object({}) do |a, hash|
    name = [a.name]
    name.unshift(a.namespace.prefix) if a.namespace && a.namespace.prefix
    hash[name.join(':')] = a.value
  end
end
node_namespaces(node, opts) click to toggle source

Get node's namespaces

@param [Nokogiri::XML::Node] node @param [XMLable::Options::Storage] opts

@return [Hash{String => String}]

# File lib/xmlable/exports/xml_exporter.rb, line 69
def node_namespaces(node, opts)
  return {} unless node.respond_to?(:namespace_definitions)

  node.namespace_definitions.each_with_object({}) do |n, obj|
    name = ["xmlns", n.prefix].compact.join(":")
    obj[name] = n.href
  end
end
node_ns_definition(node, ns) click to toggle source

Get element's namespace definition

@param [Nokogiri::XML::Element] node @param [Nokogiri::XML::Namespace, String] ns

@return [Nokogiri::XML::Namespace, nil] returns namespace if it's found,

otherwise +nil+
# File lib/xmlable/exports/xml_exporter.rb, line 131
def node_ns_definition(node, ns)
  prefix = ns.is_a?(Nokogiri::XML::Namespace) ? ns.prefix : ns
  node.namespace_definitions.find { |n| n.prefix == prefix }
end