class Lutaml::Model::Xml::OgaAdapter
def self.name_of(element)
def self.name_of(element) case element when Moxml::Text "text" when Moxml::Cdata "cdata" else element.name end end
def self.namespaced_attr_name(attribute)
def self.namespaced_attr_name(attribute) attr_ns = attribute.namespace attr_name = attribute.name return attr_name unless attr_ns prefix = attr_name == "lang" ? attr_ns.prefix : attr_ns.uri [prefix, attr_name].compact.join(":") end
def self.namespaced_name_of(node)
def self.namespaced_name_of(node) return name_of(node) unless node.respond_to?(:namespace) [node&.namespace&.uri, node.name].compact.join(":") end
def self.order_of(element)
def self.order_of(element) element.children.map do |child| instance_args = if TEXT_CLASSES.include?(child.class) ["Text", "text"] else ["Element", name_of(child)] end Element.new(*instance_args) end end
def self.parse(xml, options = {})
def self.parse(xml, options = {}) parsed = Moxml::Adapter::Oga.parse(xml) @root = Oga::Element.new(parsed.children.first) new(@root, encoding(xml, options)) end
def self.prefixed_name_of(node)
def self.prefixed_name_of(node) return name_of(node) if TEXT_CLASSES.include?(node.class) [node&.namespace&.prefix, node.name].compact.join(":") end
def self.text_of(element)
def self.text_of(element) element.content end
def attributes_hash(element)
def attributes_hash(element) result = Lutaml::Model::MappingHash.new element.attributes.each do |attr| if attr.name == "schemaLocation" result["__schema_location"] = { namespace: attr.namespace, prefix: attr.namespace.prefix, schema_location: attr.value, } else result[self.class.namespaced_attr_name(attr)] = attr.value end end result end
def build_ordered_element(builder, element, options = {})
def build_ordered_element(builder, element, options = {}) mapper_class = determine_mapper_class(element, options) xml_mapping = mapper_class.mappings_for(:xml) return xml unless xml_mapping attributes = build_attributes(element, xml_mapping).compact tag_name = options[:tag_name] || xml_mapping.root_element builder.create_and_add_element(tag_name, attributes: attributes) do |el| index_hash = {} content = [] element.element_order.each do |object| object_key = "#{object.name}-#{object.type}" index_hash[object_key] ||= -1 curr_index = index_hash[object_key] += 1 element_rule = xml_mapping.find_by_name(object.name, type: object.type) next if element_rule.nil? attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class) value = attribute_value_for(element, element_rule) next if element_rule == xml_mapping.content_mapping && element_rule.cdata && object.text? if element_rule == xml_mapping.content_mapping text = xml_mapping.content_mapping.serialize(element) text = text[curr_index] if text.is_a?(Array) next el.add_text(el, text, cdata: element_rule.cdata) if element.mixed? content << text elsif !value.nil? || element_rule.render_nil? value = value[curr_index] if attribute_def.collection? add_to_xml( el, element, nil, value, options.merge( attribute: attribute_def, rule: element_rule, mapper_class: mapper_class, ), ) end end el.add_text(el, content.join) end end
def order
def order children.map do |child| type = child.text? ? "Text" : "Element" Element.new(type, child.unprefixed_name) end end
def to_xml(options = {})
def to_xml(options = {}) builder_options = {} builder_options[:encoding] = if options.key?(:encoding) options[:encoding] elsif options.key?(:parse_encoding) options[:parse_encoding] else "UTF-8" end builder = Builder::Oga.build(builder_options) do |xml| if @root.is_a?(Oga::Element) @root.build_xml(xml) else build_element(xml, @root, options) end end xml_data = builder.to_xml options[:declaration] ? declaration(options) + xml_data : xml_data end