Module: Lutaml::Xml::DeclarationPlanQuery

Defined in:
lib/lutaml/xml/declaration_plan_query.rb

Overview

Query helper for DeclarationPlan tree structure

Provides OOP interface for extracting namespace information from DeclarationPlan without adding query methods to plan itself.

ARCHITECTURE: Separate query logic from data structure (MECE)

DeclarationPlan is a pure data structure (tree of ElementNode objects). This module contains all query/search logic for that structure.

Class Method Summary collapse

Class Method Details

.declared_at_root_default_format?(plan, namespace_class) ⇒ Boolean

Check if namespace is declared at root with default format

This is useful for determining if child elements can inherit via the default namespace without needing prefixes.

Parameters:

  • plan (DeclarationPlan)

    The declaration plan

  • namespace_class (Class)

    XmlNamespace class

Returns:

  • (Boolean)

    true if declared at root with default format



61
62
63
64
65
66
67
68
69
# File 'lib/lutaml/xml/declaration_plan_query.rb', line 61

def self.declared_at_root_default_format?(plan, namespace_class)
  return false unless namespace_class
  return false if namespace_class == :blank # :blank has no URI

  uri = namespace_class.uri
  ns_info = find_namespace_by_uri(plan, uri)

  ns_info && ns_info[:declared_at] == :here && ns_info[:format] == :default
end

.element_needs_xmlns_blank?(plan, element) ⇒ Boolean

Check if element needs xmlns=“” based on plan

An element needs xmlns=“” if:

  1. It has no namespace (blank namespace)

  2. Its parent uses default namespace format (xmlns=“…”)

This is W3C compliant - blank namespace children must explicitly opt out of parent’s default namespace.

Parameters:

  • plan (DeclarationPlan)

    The declaration plan

  • element (XmlDataModel::XmlElement)

    Element to check

Returns:

  • (Boolean)

    true if element needs xmlns=“”



44
45
46
47
48
49
50
51
# File 'lib/lutaml/xml/declaration_plan_query.rb', line 44

def self.element_needs_xmlns_blank?(plan, element)
  # Element with namespace doesn't need xmlns=""
  return false if element.namespace_class

  # Check if root declares default namespace (xmlns="...")
  # If root has default namespace (key nil), blank children need xmlns=""
  plan.root_node.hoisted_declarations.key?(nil)
end

.find_namespace_by_uri(plan, uri) ⇒ Hash?

Find namespace declaration in plan by URI

Searches the root node’s hoisted declarations for a namespace with the given URI and returns information about it.

Parameters:

  • plan (DeclarationPlan)

    The declaration plan

  • uri (String)

    Namespace URI to search for

Returns:

  • (Hash, nil)

    { prefix: String|nil, format: Symbol, declared_at: Symbol, uri: String }

    • prefix: nil for default format, “prefix” for prefix format

    • format: :default or :prefix

    • declared_at: :here (root hoisted) or :local_on_use

    • uri: the namespace URI



27
28
29
30
# File 'lib/lutaml/xml/declaration_plan_query.rb', line 27

def self.find_namespace_by_uri(plan, uri)
  # Performance: Use O(1) lookup on DeclarationPlan
  plan.find_namespace_by_uri(uri)
end

.prefix_for(plan, namespace_class) ⇒ String?

Get prefix for namespace from plan

Returns the prefix string if namespace uses prefix format, or nil if it uses default format or is not found.

Parameters:

  • plan (DeclarationPlan)

    The declaration plan

  • namespace_class (Class)

    XmlNamespace class

Returns:

  • (String, nil)

    Prefix string or nil



94
95
96
97
98
99
100
101
102
# File 'lib/lutaml/xml/declaration_plan_query.rb', line 94

def self.prefix_for(plan, namespace_class)
  return nil unless namespace_class
  return nil if namespace_class == :blank # :blank has no URI

  uri = namespace_class.uri
  ns_info = find_namespace_by_uri(plan, uri)

  ns_info&.dig(:prefix)
end

.prefix_format?(plan, namespace_class) ⇒ Boolean

Check if namespace uses prefix format in plan

Parameters:

  • plan (DeclarationPlan)

    The declaration plan

  • namespace_class (Class)

    XmlNamespace class

Returns:

  • (Boolean)

    true if namespace uses prefix format



76
77
78
79
80
81
82
83
84
# File 'lib/lutaml/xml/declaration_plan_query.rb', line 76

def self.prefix_format?(plan, namespace_class)
  return false unless namespace_class
  return false if namespace_class == :blank # :blank has no URI

  uri = namespace_class.uri
  ns_info = find_namespace_by_uri(plan, uri)

  ns_info && ns_info[:format] == :prefix
end