Sha256: ec164fc04020d37041a84086361ea4238788392ba81c69c0b102487b99faa917

Contents?: true

Size: 1.92 KB

Versions: 2

Compression:

Stored size: 1.92 KB

Contents

require "oga"
require_relative "xml_document"

module Lutaml
  module Model
    module XmlAdapter
      class OgaAdapter < XmlDocument
        def self.parse(xml, _options = {})
          parsed = Oga.parse_xml(xml)
          root = OgaElement.new(parsed)
          new(root)
        end

        def to_h
          { @root.name => parse_element(@root) }
        end

        def to_xml(options = {})
          builder = Oga::XML::Builder.new
          build_element(builder, @root, options)
          xml_data = builder.to_xml
          options[:declaration] ? declaration(options) + xml_data : xml_data
        end

        private

        def build_element(builder, element, options = {})
          attributes = build_attributes(element.attributes)
          builder.element(element.name, attributes) do
            element.children.each do |child|
              build_element(builder, child, options)
            end
            builder.text(element.text) if element.text
          end
        end

        def build_attributes(attributes)
          attributes.transform_values(&:value)
        end

        def parse_element(element)
          result = { "_text" => element.text }
          element.children.each do |child|
            next if child.is_a?(Oga::XML::Text)

            result[child.name] ||= []
            result[child.name] << parse_element(child)
          end
          result
        end
      end

      class OgaElement < XmlElement
        def initialize(node)
          attributes = node.attributes.each_with_object({}) do |attr, hash|
            hash[attr.name] = XmlAttribute.new(attr.name, attr.value)
          end
          super(node.name, attributes, parse_children(node), node.text)
        end

        private

        def parse_children(node)
          node.children.select do |child|
            child.is_a?(Oga::XML::Element)
          end.map { |child| OgaElement.new(child) }
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
lutaml-model-0.4.0 lib/lutaml/model/xml_adapter/oga_adapter.rb
lutaml-model-0.3.30 lib/lutaml/model/xml_adapter/oga_adapter.rb