class NdrImport::Xml::Table

This class maintains the state of a xml table mapping and encapsulates the logic required to transform a table of data into “records”. Particular attention has been made to use enumerables throughout to help with the transformation of large quantities of data.

Public Class Methods

all_valid_options() click to toggle source
Calls superclass method NdrImport::Table::all_valid_options
# File lib/ndr_import/xml/table.rb, line 10
def self.all_valid_options
  super - %w[delimiter header_lines footer_lines]
end

Public Instance Methods

header_lines() click to toggle source
# File lib/ndr_import/xml/table.rb, line 14
def header_lines
  0
end
transform_line(line, index) { |klass, fields, index| ... } click to toggle source

This method transforms an incoming line (element) of xml data by applying each of the klass masked mappings to the line and yielding the klass and fields for each mapped klass.

# File lib/ndr_import/xml/table.rb, line 25
def transform_line(line, index)
  return enum_for(:transform_line, line, index) unless block_given?

  raise 'Not an Nokogiri::XML::Element!' unless line.is_a? Nokogiri::XML::Element

  validate_column_mappings(line)

  xml_line = column_xpaths.map { |column_xpath| line.xpath(column_xpath).inner_text }

  masked_mappings.each do |klass, klass_mappings|
    fields = mapped_line(xml_line, klass_mappings)
    next if fields[:skip].to_s == 'true'.freeze
    yield(klass, fields, index)
  end
end

Private Instance Methods

build_xpath_from(column) click to toggle source
# File lib/ndr_import/xml/table.rb, line 68
def build_xpath_from(column)
  column_name = column_name_from(column)
  column['xml_cell'].presence ? relative_path_from(column, column_name) : column_name
end
column_name_from(column) click to toggle source
# File lib/ndr_import/xml/table.rb, line 49
def column_name_from(column)
  column[Strings::COLUMN] || column[Strings::STANDARD_MAPPING]
end
column_xpaths() click to toggle source
# File lib/ndr_import/xml/table.rb, line 53
def column_xpaths
  @column_xpaths ||= columns.map { |column| build_xpath_from(column) }
end
mappable_xpaths_from(line) click to toggle source
# File lib/ndr_import/xml/table.rb, line 57
def mappable_xpaths_from(line)
  xpaths = []

  line.xpath('.//*[not(child::*)]').each do |node|
    xpath = node.path.sub(line.path + '/', '')
    xpaths << xpath
    node.attributes.each_key { |key| xpaths << "#{xpath}/@#{key}" }
  end
  xpaths
end
relative_path_from(column, colum_name) click to toggle source
# File lib/ndr_import/xml/table.rb, line 73
def relative_path_from(column, colum_name)
  xml_cell      = column['xml_cell']
  relative_path = xml_cell['relative_path'].presence ? xml_cell['relative_path'] : nil
  attribute     = xml_cell['attribute'].presence ? '@' + xml_cell['attribute'] : nil

  if relative_path && attribute
    relative_path + '/' + colum_name + '/' + attribute
  elsif relative_path
    relative_path + '/' + colum_name
  elsif attribute
    colum_name + '/' + attribute
  else
    colum_name
  end
end
validate_column_mappings(line) click to toggle source

Ensure every leaf is accounted for in the column mappings

# File lib/ndr_import/xml/table.rb, line 44
def validate_column_mappings(line)
  missing_nodes = mappable_xpaths_from(line) - column_xpaths
  raise "Unmapped data! #{missing_nodes}" unless missing_nodes.empty?
end