Module: Lutaml::Xml::Adapter::XmlSerializer

Included in:
BaseAdapter
Defined in:
lib/lutaml/xml/adapter/xml_serializer.rb

Overview

Handles the XML serialization pipeline.

Responsible for converting model instances and XmlElement trees into XML output via builder objects. Includes the top-level ‘to_xml` entry point and supporting methods for rendering XmlElement structures with namespace declaration plans.

Instance Method Summary collapse

Instance Method Details

#add_value(xml, value, attribute, cdata: false) ⇒ Object

Add text content to XML builder

Parameters:

  • xml (Builder)

    the XML builder

  • value (Object)

    the value to add

  • attribute (Attribute, nil)

    the attribute definition

  • cdata (Boolean) (defaults to: false)

    whether to use CDATA



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/lutaml/xml/adapter/xml_serializer.rb', line 19

def add_value(xml, value, attribute, cdata: false)
  if !value.nil?
    if attribute.nil?
      # For delegated attributes where attribute is nil, just use the raw value
      xml.add_text(xml, value.to_s, cdata: cdata)
    elsif attribute.transform.is_a?(Class) && attribute.transform < Lutaml::Model::ValueTransformer
      # Value has already been transformed, use it directly
      xml.add_text(xml, value.to_s, cdata: cdata)
    else
      # Normal serialization through attribute type system
      serialized_value = attribute.serialize(value, :xml, register)
      if attribute.raw?
        xml.add_xml_fragment(xml, value)
      elsif serialized_value.is_a?(Hash)
        serialized_value.each do |key, val|
          xml.create_and_add_element(key) do |element|
            element.text(val)
          end
        end
      else
        xml.add_text(xml, serialized_value, cdata: cdata)
      end
    end
  end
end

#build_serializable_xml(xml, options) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/lutaml/xml/adapter/xml_serializer.rb', line 64

def build_serializable_xml(xml, options)
  original_model = nil
  xml_element = transformable_xml_element(options) do |model|
    original_model = model
  end

  if xml_element
    render_xml_element(xml, xml_element, original_model, options)
  else
    render_legacy_model(xml, options)
  end
end

#build_xml_element_with_plan(builder, xml_element, plan, options = {}) ⇒ Object

Build XML from XmlDataModel::XmlElement structure with a declaration plan

Parameters:

  • builder (Builder)

    XML builder

  • xml_element (XmlDataModel::XmlElement)

    root element

  • plan (DeclarationPlan)

    the declaration plan

  • options (Hash) (defaults to: {})

    serialization options



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/lutaml/xml/adapter/xml_serializer.rb', line 83

def build_xml_element_with_plan(builder, xml_element, plan,
    options = {})
  # Add processing instructions before the root element
  if xml_element.respond_to?(:processing_instructions)
    xml_element.processing_instructions.each do |pi|
      builder.add_processing_instruction(pi.target, pi.content)
    end
  end

  build_plan_node(builder, xml_element, plan.root_node, plan: plan,
                                                        options: options)
end

#to_xml(options = {}) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/lutaml/xml/adapter/xml_serializer.rb', line 45

def to_xml(options = {})
  # Accept xml_declaration from options if present (for model serialization)
  @xml_declaration = options[:xml_declaration] if options[:xml_declaration]

  encoding = determine_encoding(options)
  builder_options = {}
  builder_options[:encoding] = encoding if encoding

  builder = self.class::BUILDER_CLASS.build(builder_options) do |xml|
    if root.is_a?(self.class::PARSED_ELEMENT_CLASS)
      root.build_xml(xml)
    else
      build_serializable_xml(xml, options)
    end
  end

  finalize_adapter_xml(builder.to_xml, encoding, options)
end