Class: WSDL::Schema::Node
- Inherits:
-
Object
- Object
- WSDL::Schema::Node
- Defined in:
- lib/wsdl/schema/node.rb
Overview
Unified representation of all XSD schema nodes.
Instead of a deep class hierarchy where most classes are empty, this single class represents all XSD constructs and uses the #kind attribute to determine behavior.
Constant Summary collapse
- ELEMENT_TERMINATORS =
Node kinds that terminate element collection (contain no child elements).
Set[ :attribute, :annotation, :simpleContent ].freeze
- ATTRIBUTE_TERMINATORS =
Node kinds that terminate attribute collection.
Set[ :annotation ].freeze
- ELEMENT_KINDS =
Node kinds representing actual schema elements.
Set[:element, :any].freeze
- ATTRIBUTE_KINDS =
Node kinds representing attributes.
Set[:attribute].freeze
- INLINE_TYPE_KINDS =
Node kinds that can have inline type definitions.
Set[:complexType, :simpleType].freeze
Instance Attribute Summary collapse
-
#kind ⇒ Symbol
readonly
The XSD element type (:element, :complexType, :sequence, etc.).
-
#namespaces ⇒ Hash{String => String}
readonly
XML namespace declarations in scope.
-
#xml_node ⇒ Nokogiri::XML::Node
readonly
The underlying XML node.
Common Attributes collapse
-
#[](attr_name) ⇒ String?
Accesses any attribute from the underlying node.
-
#base ⇒ String?
The base type for restrictions/extensions.
-
#default ⇒ String?
The default value.
-
#fixed ⇒ String?
The fixed value.
-
#form ⇒ String
Returns the element form (qualified or unqualified).
-
#name ⇒ String?
The local name of this node.
-
#namespace ⇒ String?
The target namespace URI.
-
#nillable? ⇒ Boolean
Whether this element allows nil values (xsi:nil="true").
-
#ref ⇒ String?
The qualified element/attribute reference.
-
#type ⇒ String?
The qualified type reference.
-
#use ⇒ String
The use constraint ('optional' or 'required').
Children & Traversal collapse
-
#attributes(memo = [], limits: nil) ⇒ Array<Node>
Collects all attribute definitions from this node and descendants.
-
#children ⇒ Array<Node>
Returns the parsed child nodes.
-
#elements(memo = [], limits: nil) ⇒ Array<Node>
Collects all element definitions from this node and descendants.
-
#empty? ⇒ Boolean
Returns whether this node has no meaningful content.
Type Resolution collapse
-
#inline_type ⇒ Node?
Returns the inline type definition if present.
-
#restriction_base ⇒ String?
Returns the base type from a restriction child.
-
#type_id ⇒ String?
Returns a unique identifier for this type.
xs:any Wildcard Support collapse
-
#any? ⇒ Boolean
True if this is an xs:any wildcard.
-
#namespace_constraint ⇒ String
Returns the namespace constraint for wildcards.
-
#process_contents ⇒ String
Returns how wildcard content should be validated.
Cardinality collapse
-
#max_occurs ⇒ String
The maxOccurs value ('1', 'unbounded', etc.).
-
#min_occurs ⇒ String
The minOccurs value ('0', '1', etc.).
-
#multiple? ⇒ Boolean
Returns whether this element can appear multiple times.
-
#optional? ⇒ Boolean
Returns whether this element is optional.
-
#required? ⇒ Boolean
Returns whether this element is required.
Pattern Matching collapse
-
#deconstruct_keys(_keys) ⇒ Hash
Supports Ruby pattern matching.
Instance Method Summary collapse
-
#initialize(xml_node, collection, context = {}) ⇒ Node
constructor
Creates a new Node from an XSD element.
-
#inspect ⇒ String
Returns a string representation for debugging.
Constructor Details
#initialize(xml_node, collection, context = {}) ⇒ Node
Creates a new Node from an XSD element.
58 59 60 61 62 63 64 65 66 |
# File 'lib/wsdl/schema/node.rb', line 58 def initialize(xml_node, collection, context = {}) @xml_node = xml_node @collection = collection @context = context @kind = xml_node.name.to_sym @attributes_hash = extract_attributes(xml_node) @namespaces = xml_node.namespaces.freeze end |
Instance Attribute Details
#kind ⇒ Symbol (readonly)
Returns the XSD element type (:element, :complexType, :sequence, etc.).
69 70 71 |
# File 'lib/wsdl/schema/node.rb', line 69 def kind @kind end |
#namespaces ⇒ Hash{String => String} (readonly)
Returns XML namespace declarations in scope.
75 76 77 |
# File 'lib/wsdl/schema/node.rb', line 75 def namespaces @namespaces end |
#xml_node ⇒ Nokogiri::XML::Node (readonly)
Returns the underlying XML node.
72 73 74 |
# File 'lib/wsdl/schema/node.rb', line 72 def xml_node @xml_node end |
Instance Method Details
#[](attr_name) ⇒ String?
Accesses any attribute from the underlying node.
136 137 138 |
# File 'lib/wsdl/schema/node.rb', line 136 def [](attr_name) @attributes_hash[attr_name] end |
#any? ⇒ Boolean
Returns true if this is an xs:any wildcard.
258 259 260 |
# File 'lib/wsdl/schema/node.rb', line 258 def any? kind == :any end |
#attributes(memo = [], limits: nil) ⇒ Array<Node>
Collects all attribute definitions from this node and descendants.
Traverses the type hierarchy to find all xs:attribute definitions. Handles attributeGroup references.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/wsdl/schema/node.rb', line 203 def attributes(memo = [], limits: nil) return memo if ATTRIBUTE_TERMINATORS.include?(kind) return resolve_attribute_group_ref(memo, limits:) if kind == :attributeGroup && ref children.each do |child| if ATTRIBUTE_KINDS.include?(child.kind) memo << child validate_attribute_count!(memo.size, limits) else memo = child.attributes(memo, limits:) end end memo end |
#base ⇒ String?
Returns the base type for restrictions/extensions.
95 96 97 |
# File 'lib/wsdl/schema/node.rb', line 95 def base @attributes_hash['base'] end |
#children ⇒ Array<Node>
Returns the parsed child nodes.
147 148 149 |
# File 'lib/wsdl/schema/node.rb', line 147 def children @children ||= @xml_node.element_children.map { |n| Node.new(n, @collection, @context) } end |
#deconstruct_keys(_keys) ⇒ Hash
Supports Ruby pattern matching.
325 326 327 328 329 330 331 332 333 |
# File 'lib/wsdl/schema/node.rb', line 325 def deconstruct_keys(_keys) { kind: kind, name: name, type: type, ref: ref, namespace: namespace } end |
#default ⇒ String?
Returns the default value.
105 106 107 |
# File 'lib/wsdl/schema/node.rb', line 105 def default @attributes_hash['default'] end |
#elements(memo = [], limits: nil) ⇒ Array<Node>
Collects all element definitions from this node and descendants.
Traverses the type hierarchy to find all xs:element definitions, which represent the actual content model of complex types. Handles extension base type inheritance.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/wsdl/schema/node.rb', line 177 def elements(memo = [], limits: nil) return memo if ELEMENT_TERMINATORS.include?(kind) include_base_type_elements(memo, limits:) if kind == :extension children.each do |child| if ELEMENT_KINDS.include?(child.kind) memo << child validate_element_count!(memo.size, limits) else memo = child.elements(memo, limits:) end end memo end |
#empty? ⇒ Boolean
Returns whether this node has no meaningful content.
A node is considered empty if it has no children, or if its only children are empty compositors (sequence, all, choice with no elements).
157 158 159 160 161 162 163 164 165 |
# File 'lib/wsdl/schema/node.rb', line 157 def empty? return true if children.empty? # Check if all children are empty compositors compositor_kinds = i[sequence all choice] children.all? do |child| compositor_kinds.include?(child.kind) && child.children.empty? end end |
#fixed ⇒ String?
Returns the fixed value.
110 111 112 |
# File 'lib/wsdl/schema/node.rb', line 110 def fixed @attributes_hash['fixed'] end |
#form ⇒ String
Returns the element form (qualified or unqualified).
127 128 129 130 |
# File 'lib/wsdl/schema/node.rb', line 127 def form @attributes_hash['form'] || (@context[:element_form_default] == 'qualified' ? 'qualified' : 'unqualified') end |
#inline_type ⇒ Node?
Returns the inline type definition if present.
An inline type is a complex or simple type defined directly within the element rather than referenced by name. Skips annotation elements.
230 231 232 |
# File 'lib/wsdl/schema/node.rb', line 230 def inline_type children.find { |c| INLINE_TYPE_KINDS.include?(c.kind) } end |
#inspect ⇒ String
Returns a string representation for debugging.
340 341 342 343 |
# File 'lib/wsdl/schema/node.rb', line 340 def inspect attrs = @attributes_hash.map { |k, v| "#{k}=#{v.inspect}" }.join(' ') "#<Schema::Node:#{kind} #{attrs}>" end |
#max_occurs ⇒ String
Returns the maxOccurs value ('1', 'unbounded', etc.).
281 282 283 |
# File 'lib/wsdl/schema/node.rb', line 281 def max_occurs @attributes_hash['maxOccurs'] || '1' end |
#min_occurs ⇒ String
Returns the minOccurs value ('0', '1', etc.).
286 287 288 |
# File 'lib/wsdl/schema/node.rb', line 286 def min_occurs @attributes_hash['minOccurs'] || '1' end |
#multiple? ⇒ Boolean
Returns whether this element can appear multiple times.
293 294 295 |
# File 'lib/wsdl/schema/node.rb', line 293 def multiple? max_occurs == 'unbounded' || max_occurs.to_i > 1 end |
#name ⇒ String?
Returns the local name of this node.
80 81 82 |
# File 'lib/wsdl/schema/node.rb', line 80 def name @attributes_hash['name'] end |
#namespace ⇒ String?
Returns the target namespace URI.
120 121 122 |
# File 'lib/wsdl/schema/node.rb', line 120 def namespace @context[:target_namespace] end |
#namespace_constraint ⇒ String
Returns the namespace constraint for wildcards.
265 266 267 |
# File 'lib/wsdl/schema/node.rb', line 265 def namespace_constraint @attributes_hash['namespace'] || '##any' end |
#nillable? ⇒ Boolean
Returns whether this element allows nil values (xsi:nil="true").
115 116 117 |
# File 'lib/wsdl/schema/node.rb', line 115 def nillable? @attributes_hash['nillable'] == 'true' end |
#optional? ⇒ Boolean
Returns whether this element is optional.
300 301 302 |
# File 'lib/wsdl/schema/node.rb', line 300 def optional? min_occurs == '0' end |
#process_contents ⇒ String
Returns how wildcard content should be validated.
272 273 274 |
# File 'lib/wsdl/schema/node.rb', line 272 def process_contents @attributes_hash['processContents'] || 'strict' end |
#ref ⇒ String?
Returns the qualified element/attribute reference.
90 91 92 |
# File 'lib/wsdl/schema/node.rb', line 90 def ref @attributes_hash['ref'] end |
#required? ⇒ Boolean
Returns whether this element is required.
307 308 309 |
# File 'lib/wsdl/schema/node.rb', line 307 def required? !optional? end |
#restriction_base ⇒ String?
Returns the base type from a restriction child.
237 238 239 240 |
# File 'lib/wsdl/schema/node.rb', line 237 def restriction_base restriction = children.find { |c| c.kind == :restriction } restriction&.base end |
#type ⇒ String?
Returns the qualified type reference.
85 86 87 |
# File 'lib/wsdl/schema/node.rb', line 85 def type @attributes_hash['type'] end |
#type_id ⇒ String?
Returns a unique identifier for this type.
Used to detect recursive type definitions during element building.
247 248 249 250 251 |
# File 'lib/wsdl/schema/node.rb', line 247 def type_id return nil unless i[complexType element].include?(kind) "#{namespace}:#{name}" end |
#use ⇒ String
Returns the use constraint ('optional' or 'required').
100 101 102 |
# File 'lib/wsdl/schema/node.rb', line 100 def use @attributes_hash['use'] || 'optional' end |