Class: Lutaml::Xml::Namespace

Inherits:
Object
  • Object
show all
Defined in:
lib/lutaml/xml/namespace.rb

Overview

Base class for defining XML namespaces with full XSD generation support.

This class provides a declarative DSL for defining namespace metadata that follows W3C XML Namespace and XSD specifications.

Examples:

Basic namespace definition

class ContactNamespace < Lutaml::Xml::Namespace
  uri 'https://example.com/schemas/contact/v1'
  schema_location 'https://example.com/schemas/contact/v1/contact.xsd'
  prefix_default 'contact'
end

Full namespace definition with XSD features

class ContactNamespace < Lutaml::Xml::Namespace
  uri 'https://example.com/schemas/contact/v1'
  schema_location 'https://example.com/schemas/contact/v1/contact.xsd'
  prefix_default 'contact'
  element_form_default :qualified
  attribute_form_default :unqualified
  version '1.0'

  imports AddressNamespace
  includes 'contact-common.xsd'

  annotation do
    documentation "Contact information schema for Example Corp"
  end
end

Constant Summary collapse

W3C_RESERVED_URIS =

W3C-reserved namespace URIs and recommended alternatives

{
  "http://www.w3.org/XML/1998/namespace" =>
    "Use Lutaml::Xml::W3c::XmlNamespace for xml: attributes (xml:lang, xml:space, etc.)",
  "http://www.w3.org/2001/XMLSchema-instance" =>
    "Use Lutaml::Xml::W3c::XsiNamespace for xsi: attributes (xsi:type, xsi:nil, etc.)",
  "http://www.w3.org/1999/xlink" =>
    "Use Lutaml::Xml::W3c::XlinkNamespace for xlink: attributes (xlink:href, xlink:type, etc.)",
  "http://www.w3.org/2001/XMLSchema" =>
    "Use Lutaml::Xml::W3c::XsNamespace for xs: schema elements (xs:element, xs:complexType, etc.)",
}.freeze
W3C_RESERVED_PREFIXES =

W3C-reserved prefixes and recommended alternatives

{
  "xml" => "The 'xml' prefix is RESERVED per W3C. Use Lutaml::Xml::W3c::XmlNamespace for xml: attributes.",
  "xsi" => "Use Lutaml::Xml::W3c::XsiNamespace for xsi: attributes.",
  "xlink" => "Use Lutaml::Xml::W3c::XlinkNamespace for xlink: attributes.",
  "xs" => "Use Lutaml::Xml::W3c::XsNamespace for xs: schema elements.",
  "xsd" => "Use Lutaml::Xml::W3c::XsNamespace for xs: schema elements.",
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prefix: nil) ⇒ Namespace

Initialize instance with resolved metadata

Parameters:

  • prefix (String, Symbol, nil) (defaults to: nil)

    optional prefix override



332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/lutaml/xml/namespace.rb', line 332

def initialize(prefix: nil)
  @uri = self.class.uri
  @schema_location = self.class.schema_location
  @prefix = prefix&.to_s || self.class.prefix_default
  @element_form_default = self.class.element_form_default
  @attribute_form_default = self.class.attribute_form_default
  @version = self.class.version
  @imports = self.class.imports
  @includes = self.class.includes
  @documentation = self.class.documentation

  check_w3c_reserved!
end

Instance Attribute Details

#attribute_form_defaultObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def attribute_form_default
  @attribute_form_default
end

#documentationObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def documentation
  @documentation
end

#element_form_defaultObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def element_form_default
  @element_form_default
end

#importsObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def imports
  @imports
end

#includesObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def includes
  @includes
end

#prefixObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def prefix
  @prefix
end

#schema_locationObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def schema_location
  @schema_location
end

#uriObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def uri
  @uri
end

#versionObject (readonly)

Instance attributes for runtime resolution



325
326
327
# File 'lib/lutaml/xml/namespace.rb', line 325

def version
  @version
end

Class Method Details

.all_urisArray<String>

Get all URIs for this namespace (canonical + aliases)

Performance: Cache all_uris as frozen array (called millions of times)

Returns:

  • (Array<String>)

    Array of all URI strings



113
114
115
# File 'lib/lutaml/xml/namespace.rb', line 113

def all_uris
  @all_uris ||= ([uri].compact + uri_aliases).freeze
end

.annotation { ... } ⇒ Proc?

Define annotation block for the schema

Yields:

  • block for defining annotations

Returns:

  • (Proc, nil)

    the annotation block



218
219
220
221
# File 'lib/lutaml/xml/namespace.rb', line 218

def annotation(&block)
  @annotation_value = block if block
  @annotation_value
end

.attribute_form_default(value = nil) ⇒ Symbol

Get or set attribute form default (:qualified or :unqualified)

Controls whether locally declared attributes must be namespace-qualified in instance documents.

Parameters:

  • value (Symbol, nil) (defaults to: nil)

    :qualified or :unqualified

Returns:

  • (Symbol)

    the attribute form default (defaults to :unqualified per W3C)



160
161
162
163
164
165
166
# File 'lib/lutaml/xml/namespace.rb', line 160

def attribute_form_default(value = nil)
  if value
    validate_form_value!(value, "attribute_form_default")
    @attribute_form_default_value = value
  end
  @attribute_form_default_value || :unqualified # W3C default is :unqualified
end

.build(prefix: nil) ⇒ Namespace

Create an instance with optional runtime prefix override

Parameters:

  • prefix (String, Symbol, nil) (defaults to: nil)

    runtime prefix override

Returns:

  • (Namespace)

    instance with resolved metadata



250
251
252
# File 'lib/lutaml/xml/namespace.rb', line 250

def build(prefix: nil)
  new(prefix: prefix)
end

.documentation(text = nil) ⇒ String?

Get or set documentation text

Parameters:

  • text (String, nil) (defaults to: nil)

    the documentation text

Returns:

  • (String, nil)

    the documentation text



227
228
229
230
# File 'lib/lutaml/xml/namespace.rb', line 227

def documentation(text = nil)
  @documentation_value = text if text
  @documentation_value
end

.element_form_default(value = nil) ⇒ Symbol

Get or set element form default (:qualified or :unqualified)

Controls whether locally declared elements must be namespace-qualified in instance documents.

Parameters:

  • value (Symbol, nil) (defaults to: nil)

    :qualified or :unqualified

Returns:

  • (Symbol)

    the element form default (defaults to :unqualified)



144
145
146
147
148
149
150
151
# File 'lib/lutaml/xml/namespace.rb', line 144

def element_form_default(value = nil)
  if value
    validate_form_value!(value, "element_form_default")
    @element_form_default_value = value
    @element_form_default_set = true
  end
  @element_form_default_value || :unqualified
end

.element_form_default_set?Boolean

Check if element_form_default was explicitly set (vs defaulted to :unqualified)

Returns:

  • (Boolean)

    true if element_form_default was explicitly set on this class



302
303
304
# File 'lib/lutaml/xml/namespace.rb', line 302

def element_form_default_set?
  @element_form_default_set == true
end

.imports(*namespaces) ⇒ Array<Class>

Add imported namespaces (xs:import in XSD)

Used when referencing types from other namespaces.

Parameters:

  • namespaces (Array<Class>)

    Namespace classes to import

Returns:

  • (Array<Class>)

    all imported namespaces



174
175
176
177
178
179
180
181
182
183
# File 'lib/lutaml/xml/namespace.rb', line 174

def imports(*namespaces)
  @imports ||= []
  if namespaces.any?
    namespaces.each do |ns|
      validate_namespace_class!(ns, "imports")
    end
    @imports.concat(namespaces)
  end
  @imports
end

.includes(*schemas) ⇒ Array<String>

Add included schema locations (xs:include in XSD)

Used when including schema components from the same namespace.

Parameters:

  • schemas (Array<String>)

    schema file locations to include

Returns:

  • (Array<String>)

    all included schemas



191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/lutaml/xml/namespace.rb', line 191

def includes(*schemas)
  @includes ||= []
  if schemas.any?
    schemas.each do |schema|
      unless schema.is_a?(String)
        raise ArgumentError,
              "includes requires String schema locations, got #{schema.class}"
      end
    end
    @includes.concat(schemas)
  end
  @includes
end

.inheritance_strategyLutaml::Xml::NamespaceInheritanceStrategy

Get the inheritance strategy for this namespace

Returns the appropriate strategy based on element_form_default setting. This determines whether child elements inherit the parent namespace.



260
261
262
263
264
265
266
267
268
269
270
# File 'lib/lutaml/xml/namespace.rb', line 260

def inheritance_strategy
  case element_form_default
  when :qualified
    Lutaml::Xml::QualifiedInheritanceStrategy.new
  when :unqualified
    Lutaml::Xml::UnqualifiedInheritanceStrategy.new
  else
    raise ArgumentError,
          "Invalid element_form_default: #{element_form_default.inspect}"
  end
end

.is_alias?(uri) ⇒ Boolean

Check if a URI is an alias of this namespace

Parameters:

  • uri (String)

    The URI to check

Returns:

  • (Boolean)

    true if the URI is an alias



105
106
107
# File 'lib/lutaml/xml/namespace.rb', line 105

def is_alias?(uri)
  uri_aliases.include?(uri)
end

.prefix_default(value = nil) ⇒ String?

Get or set the default prefix for this namespace

Parameters:

  • value (String, Symbol, nil) (defaults to: nil)

    the default prefix

Returns:

  • (String, nil)

    the default prefix



130
131
132
133
134
135
# File 'lib/lutaml/xml/namespace.rb', line 130

def prefix_default(value = nil)
  if value
    @prefix_default_value = value.to_s
  end
  @prefix_default_value
end

.schema_location(value = nil) ⇒ String?

Get or set the schema location URL

Parameters:

  • value (String, nil) (defaults to: nil)

    the schema location URL

Returns:

  • (String, nil)

    the schema location URL



121
122
123
124
# File 'lib/lutaml/xml/namespace.rb', line 121

def schema_location(value = nil)
  @schema_location_value = value if value
  @schema_location_value
end

.skip_w3c_reserved_check(value = nil) ⇒ Boolean

Skip W3C reserved namespace checks for built-in namespaces

Built-in W3C namespaces (XmlNamespace, XsiNamespace, etc.) call this to indicate they should not trigger warnings when instantiated.

Parameters:

  • value (Boolean) (defaults to: nil)

    true to skip W3C checks

Returns:

  • (Boolean)

    the skip flag value



239
240
241
242
243
244
# File 'lib/lutaml/xml/namespace.rb', line 239

def skip_w3c_reserved_check(value = nil)
  if value
    @skip_w3c_reserved_check = value
  end
  @skip_w3c_reserved_check
end

.to_keyString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generate unique key for this namespace configuration

The key is based on prefix and URI, ensuring that same config = same key. This enables proper deduplication and lookup in hash structures.

Format:

  • With prefix: “prefix:uri”

  • Without prefix (default namespace): “:uri”

Examples:

FooNamespace.to_key  # => "foo:http://example.com/foo"
BarNamespace.to_key  # => ":http://example.com/bar"

Returns:

  • (String)

    unique key for hash lookups



288
289
290
291
292
293
294
295
296
297
# File 'lib/lutaml/xml/namespace.rb', line 288

def to_key
  prefix = prefix_default
  namespace_uri = uri

  if prefix && !prefix.empty?
    "#{prefix}:#{namespace_uri}"
  else
    ":#{namespace_uri}"
  end
end

.uri(value = nil) ⇒ String?

Get or set the namespace URI

Parameters:

  • value (String, nil) (defaults to: nil)

    the namespace URI

Returns:

  • (String, nil)

    the namespace URI



60
61
62
63
# File 'lib/lutaml/xml/namespace.rb', line 60

def uri(value = nil)
  @uri_value = value if value
  @uri_value
end

.uri_aliases(*values) ⇒ Array<String>

Get or set URI aliases for this namespace

URI aliases allow a namespace to accept multiple URI variants during parsing. The canonical URI (from ‘uri`) is used for model resolution, while alias URIs are accepted on parse and serialized back as the original alias URI for round-trip fidelity.

Examples:

ReqIF namespace with trailing slash variant

class ReqIfNamespace < Lutaml::Xml::Namespace
  uri "http://www.omg.org/spec/ReqIF/20110401/reqif.xsd"
  uri_aliases "http://www.omg.org/spec/ReqIF/20110401/"
  prefix_default "reqif"
end

Multiple alias variants

class XHTMLNamespace < Lutaml::Xml::Namespace
  uri "http://www.w3.org/1999/xhtml"
  uri_aliases "http://www.w3.org/1999/xhtml/", "http://www.w3.org/1999/xhtml"
  prefix_default "xhtml"
end

Parameters:

  • values (Array<String>)

    Array of alias URI strings

Returns:

  • (Array<String>)

    All alias URIs



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/lutaml/xml/namespace.rb', line 87

def uri_aliases(*values)
  @uri_aliases ||= []
  if values.any?
    values.each do |v|
      unless v.is_a?(String) && !v.empty?
        raise ArgumentError,
              "uri_aliases requires non-empty String URIs"
      end
    end
    @uri_aliases.concat(values)
  end
  @uri_aliases
end

.version(value = nil) ⇒ String?

Get or set the schema version

Parameters:

  • value (String, nil) (defaults to: nil)

    the schema version

Returns:

  • (String, nil)

    the schema version



209
210
211
212
# File 'lib/lutaml/xml/namespace.rb', line 209

def version(value = nil)
  @version_value = value if value
  @version_value
end

Instance Method Details

#attr_nameString

Get the XML attribute name for namespace declaration

Returns:

  • (String)

    “xmlns” or “xmlns:prefix”



349
350
351
352
353
354
355
# File 'lib/lutaml/xml/namespace.rb', line 349

def attr_name
  if prefix && !prefix.empty?
    "xmlns:#{prefix}"
  else
    "xmlns"
  end
end

#attributes_qualified?Boolean

Check if this namespace is qualified for attributes

Returns:

  • (Boolean)

    true if attribute_form_default is :qualified



374
375
376
# File 'lib/lutaml/xml/namespace.rb', line 374

def attributes_qualified?
  attribute_form_default == :qualified
end

#elements_qualified?Boolean

Check if this namespace is qualified for elements

Returns:

  • (Boolean)

    true if element_form_default is :qualified



367
368
369
# File 'lib/lutaml/xml/namespace.rb', line 367

def elements_qualified?
  element_form_default == :qualified
end

#prefixed?Boolean

Check if this namespace has a prefix

Returns:

  • (Boolean)

    true if prefix is defined



360
361
362
# File 'lib/lutaml/xml/namespace.rb', line 360

def prefixed?
  !!(prefix && !prefix.empty?)
end