Class: Uniword::Ooxml::Schema::ElementSerializer

Inherits:
Object
  • Object
show all
Defined in:
lib/uniword/ooxml/schema/element_serializer.rb

Overview

Schema-driven serializer for OOXML elements.

Responsibility: Serialize ANY element to OOXML XML using schema definition. Single Responsibility - element serialization only, schema-driven.

Follows configuration over convention - serialization behavior is defined by external YAML schema, not hardcoded logic.

Examples:

Serialize a paragraph

serializer = ElementSerializer.new
xml = serializer.serialize(paragraph)

With custom schema

schema = OoxmlSchema.load('custom_schema.yml')
serializer = ElementSerializer.new(schema: schema)

Instance Method Summary collapse

Constructor Details

#initialize(schema: nil) ⇒ ElementSerializer

Initialize element serializer

Parameters:

  • schema (OoxmlSchema, nil) (defaults to: nil)

    OOXML schema (loads default if nil)



27
28
29
# File 'lib/uniword/ooxml/schema/element_serializer.rb', line 27

def initialize(schema: nil)
  @schema = schema || load_default_schema
end

Instance Method Details

#serialize(element, options = {}) ⇒ String

Serialize element to OOXML XML

Uses schema definition to determine structure, attributes, children.

Examples:

Serialize paragraph

xml = serializer.serialize(paragraph)
# => "<w:p>...</w:p>"

Parameters:

  • element (Element)

    Element to serialize

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

    Serialization options

Options Hash (options):

  • :pretty (Boolean) — default: false

    Pretty print XML

  • :standalone (Boolean) — default: true

    Include XML declaration

Returns:

  • (String)

    OOXML XML string

Raises:

  • (ArgumentError)

    if element has no schema definition



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/uniword/ooxml/schema/element_serializer.rb', line 45

def serialize(element, options = {})
  validate_element(element)

  # If element has its own to_xml method, use it directly
  # This ensures proper serialization with all attributes and content
  if element.respond_to?(:to_xml) && !options[:use_schema]
    xml_str = element.to_xml(pretty: options[:pretty])

    # Remove XML declaration unless standalone
    xml_str = xml_str.sub(/<\?xml[^?]*\?>\n?/, "") unless options.fetch(
      :standalone, false
    )

    # Add XML declaration if standalone
    xml_str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n#{xml_str}" if options.fetch(
      :standalone, false
    )

    return xml_str.strip
  end

  # Get schema definition
  schema_def = @schema.definition_for(element.class)

  # Build XML document
  doc = Nokogiri::XML::Document.new

  # Create root element with proper namespace
  root = serialize_element_to_node(doc, element, schema_def, options)
  doc.root = root

  # Format output
  xml_str = if options[:pretty]
              doc.to_xml(indent: 2)
            else
              root.to_xml
            end

  # Remove XML declaration unless standalone
  xml_str = xml_str.sub(/<\?xml[^?]*\?>\n?/, "") unless options.fetch(
    :standalone, false
  )

  # Add XML declaration if standalone
  xml_str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n#{xml_str}" if options.fetch(
    :standalone, false
  )

  xml_str.strip
end