class Cda::XmlBuilder

Attributes

model[R]
template_type[R]
xml[RW]

Public Class Methods

new(model, template_type = model.class.template_type) click to toggle source
# File lib/cda/xml_builder.rb, line 54
def initialize(model, template_type = model.class.template_type)
  @model = model
  @template_type = template_type
end

Public Instance Methods

build() click to toggle source
# File lib/cda/xml_builder.rb, line 59
def build
  build_instance_element(template_type, model)
end
build_document() click to toggle source
# File lib/cda/xml_builder.rb, line 63
def build_document
  self.xml = Nokogiri::XML::Builder.new
  if template_type != 'ClinicalDocument'
    xml.ClinicalDocument(
      'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
      'xsi:schemaLocation' => "urn:hl7-org:v3 http://xreg2.nist.gov:8080/hitspValidation/schema/cdar2c32/infrastructure/cda/C32_CDA.xsd",
      'xmlns' => "urn:hl7-org:v3",
      'xmlns:mif' => "urn:hl7-org:v3/mif"
    ) do |_|
      build
    end
  else
    build
  end
  xml.doc
end
node(name, *args, &block) click to toggle source
# File lib/cda/xml_builder.rb, line 80
def node(name, *args, &block)
  opts = args.extract_options!
  args << opts.each_with_object({}) do |pair, result|
    key, value = pair
    result[key.to_s.camelize(:lower)] = value unless value.blank?
  end
  tag_name = name.to_s
  tag_name = tag_name[0] + tag_name[1..-1].camelize(:lower)
  tag_name = "#{tag_name}_" if xml.respond_to?(tag_name)
  xml.send tag_name, *args, &block
end

Private Instance Methods

build_element(instance, element) click to toggle source
# File lib/cda/xml_builder.rb, line 94
def build_element(instance, element)
  if element.collection?
    build_elements_collection(instance, element)
  elsif !instance.nil?
    build_single_element(instance, element)
  end
end
build_elements_collection(items, element) click to toggle source
# File lib/cda/xml_builder.rb, line 113
def build_elements_collection(items, element)
  items.each { |item| build_single_element(item, element) }
end
build_instance_element(element_name, instance, additional_options = {}) click to toggle source
# File lib/cda/xml_builder.rb, line 117
def build_instance_element(element_name, instance, additional_options = {})
  return if instance.nil? || instance == ""
  meta_info = Cda::MetaInfo.for(instance.class)
  args = []
  args << instance._text if cda_mixed?(instance)
  args << additional_options.merge(get_attributes_as_hash(instance, meta_info.attributes))
  node(element_name, *args) do |_|
    meta_info.elements.each do |element|
      if element.build_method
        instance.send(element.build_method, self, element, :xml)
      else
        build_element(element.get_value(instance), element)
      end
    end
  end
end
build_single_element(instance, element) click to toggle source
# File lib/cda/xml_builder.rb, line 102
def build_single_element(instance, element)
  wrap_node_if_required(element) do
    additional_options = get_additional_options(instance, element)
    if instance.class.respond_to?(:attribute_set)
      build_instance_element(element.element_name, instance, additional_options)
    elsif element.name != :_text
      build_value_element(element.element_name, instance, additional_options)
    end
  end
end
build_value_element(element_name, value, additional_options = {}) click to toggle source
# File lib/cda/xml_builder.rb, line 138
def build_value_element(element_name, value, additional_options = {})
  node(element_name, auto_format(value), additional_options)
end
cda_mixed?(instance) click to toggle source
# File lib/cda/xml_builder.rb, line 134
def cda_mixed?(instance)
  instance.respond_to?(:mixed?) && instance.mixed?
end
detect_xsi_type(instance) click to toggle source
# File lib/cda/xml_builder.rb, line 154
def detect_xsi_type(instance)
  case instance
    when String
      'ST'
    when Cda::ANY
      get_cda_class(instance.class).name.match(/::(\w+)$/)[1]
    else
      if instance.respond_to?(:type)
        instance.type
      else
        fail "Can't detect xsi:type for #{instance.inspect}"
      end
  end
end
get_additional_options(model, element) click to toggle source
# File lib/cda/xml_builder.rb, line 142
def get_additional_options(model, element)
  options = {}
  if !templated?(model) && model.class < element.model_class
    options['xsi:type'] = detect_xsi_type(model)
  end
  options
end
get_attributes_as_hash(model, attributes) click to toggle source
# File lib/cda/xml_builder.rb, line 173
def get_attributes_as_hash(model, attributes)
  hash = attributes.each_with_object({}) do |attribute, hash|
    hash[attribute.fully_qualified_name] = auto_format(attribute.get_value(model))
  end
  hash['xsi:schemaLocation'] = model.class.schema_location if model.class.respond_to?(:schema_location)
  if model.class.respond_to?(:namespaces)
    model.class.namespaces.each do |ns, uri|
      if ns == :default
        hash['xmlns'] = uri
      else
        hash["xmlns:#{ns}"] = uri
      end
    end
  end
  hash
end
get_cda_class(cls) click to toggle source
# File lib/cda/xml_builder.rb, line 169
def get_cda_class(cls)
  cls.name.starts_with?('Cda::') ? cls : get_cda_class(cls.superclass)
end
templated?(model) click to toggle source
# File lib/cda/xml_builder.rb, line 150
def templated?(model)
  model.respond_to?(:template_id)
end
wrap_node_if_required(element) { || ... } click to toggle source
# File lib/cda/xml_builder.rb, line 190
def wrap_node_if_required(element)
  if (wrap_with = element.annotations[:wrap_with])
    node(*wrap_with) { yield }
  else
    yield
  end
end