lib/lutaml/model/xml_adapter/xml_element.rb
require_relative "xml_attribute" module Lutaml module Model module XmlAdapter class XmlElement attr_reader :attributes, :children, :namespace_prefix, :parent_document attr_accessor :adapter_node def initialize( node, attributes = {}, children = [], text = nil, parent_document: nil, namespace_prefix: nil, default_namespace: nil ) @name = extract_name(node) @namespace_prefix = namespace_prefix || extract_namespace_prefix(node) @attributes = attributes @children = children @text = text @parent_document = parent_document @default_namespace = default_namespace self.adapter_node = node end # This tells which attributes to pretty print, So we remove the # @parent_document and @adapter_node because they were causing # so much repeatative output. def pretty_print_instance_variables (instance_variables - %i[@adapter_node @parent_document]).sort end def name return @name unless namespace_prefix "#{namespace_prefix}:#{@name}" end def namespaced_name if namespaces[namespace_prefix] && !text? "#{namespaces[namespace_prefix].uri}:#{@name}" elsif @default_namespace && !text? "#{@default_namespace}:#{name}" else @name end end def unprefixed_name @name end def document XmlDocument.new(self) end def namespaces @namespaces || @parent_document&.namespaces || {} end def own_namespaces @namespaces || {} end def namespace return default_namespace unless namespace_prefix namespaces[namespace_prefix] end def attribute_is_namespace?(name) name.to_s.start_with?("xmlns") end def add_namespace(namespace) @namespaces ||= {} @namespaces[namespace.prefix] = namespace end def default_namespace namespaces[nil] || @parent_document&.namespaces&.dig(nil) end def extract_name(node) name = name_from_node(node) n = name.split(":") return name if n.length <= 1 n[1..].join(":") end def extract_namespace_prefix(node) name = name_from_node(node) n = name.to_s.split(":") return if n.length <= 1 n.first end def name_from_node(node) if node.is_a?(String) node else node.name.to_s end end def order children.map do |child| type = child.text? ? "Text" : "Element" Lutaml::Model::XmlAdapter::Element.new(type, child.unprefixed_name) end end def root self end def text return text_children.map(&:text) if children.count > 1 @text end def cdata_children find_children_by_name("#cdata-section") end def text_children find_children_by_name("text") end def find_attribute_value(attribute_name) if attribute_name.is_a?(Array) attributes.values.find do |attr| attribute_name.include?(attr.namespaced_name) end&.value else attributes.values.find do |attr| attribute_name == attr.namespaced_name end&.value end end def find_children_by_name(name) if name.is_a?(Array) children.select { |child| name.include?(child.namespaced_name) } else children.select { |child| child.namespaced_name == name } end end def find_child_by_name(name) find_children_by_name(name).first end def cdata return cdata_children.map(&:text) if children.count > 1 @text end def to_h document.to_h end end end end end