lutaml-xsd 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.rubocop_todo.yml +87 -18
  4. data/lib/lutaml/xsd/commands/element_command.rb +24 -24
  5. data/lib/lutaml/xsd/commands/namespace_command.rb +6 -6
  6. data/lib/lutaml/xsd/commands/type_command.rb +31 -31
  7. data/lib/lutaml/xsd/commands/validate_command.rb +14 -14
  8. data/lib/lutaml/xsd/coverage_analyzer.rb +1 -2
  9. data/lib/lutaml/xsd/dependency_grapher.rb +39 -55
  10. data/lib/lutaml/xsd/errors/message_builder.rb +3 -3
  11. data/lib/lutaml/xsd/errors/suggesters/fuzzy_matcher.rb +6 -10
  12. data/lib/lutaml/xsd/namespace_prefix_manager.rb +3 -3
  13. data/lib/lutaml/xsd/namespace_remapper.rb +1 -1
  14. data/lib/lutaml/xsd/package_builder.rb +2 -2
  15. data/lib/lutaml/xsd/package_validator.rb +17 -25
  16. data/lib/lutaml/xsd/schema_classifier.rb +5 -5
  17. data/lib/lutaml/xsd/schema_repository.rb +22 -32
  18. data/lib/lutaml/xsd/schema_repository_package.rb +2 -2
  19. data/lib/lutaml/xsd/schema_resolver.rb +1 -1
  20. data/lib/lutaml/xsd/spa/schema_serializer.rb +120 -178
  21. data/lib/lutaml/xsd/spa/svg/config/color_scheme.rb +8 -0
  22. data/lib/lutaml/xsd/spa/svg/renderers/element_renderer.rb +1 -1
  23. data/lib/lutaml/xsd/spa/svg/renderers/type_renderer.rb +1 -1
  24. data/lib/lutaml/xsd/spa/utils/extract_enumeration.rb +8 -13
  25. data/lib/lutaml/xsd/spa/xml_instance_generator.rb +40 -42
  26. data/lib/lutaml/xsd/type_hierarchy_analyzer.rb +7 -7
  27. data/lib/lutaml/xsd/type_searcher.rb +1 -2
  28. data/lib/lutaml/xsd/validation/facets/facet_validator.rb +1 -1
  29. data/lib/lutaml/xsd/validation/result_collector.rb +1 -3
  30. data/lib/lutaml/xsd/validation/rules/attribute_validation_rule.rb +16 -23
  31. data/lib/lutaml/xsd/validation/rules/content_model_validation_rule.rb +19 -40
  32. data/lib/lutaml/xsd/validation/rules/element_structure_rule.rb +2 -3
  33. data/lib/lutaml/xsd/validation/rules/occurrence_validation_rule.rb +7 -16
  34. data/lib/lutaml/xsd/validation/rules/type_validation_rule.rb +17 -27
  35. data/lib/lutaml/xsd/validation/xml_document.rb +3 -3
  36. data/lib/lutaml/xsd/validation/xml_element.rb +2 -2
  37. data/lib/lutaml/xsd/version.rb +1 -1
  38. data/lib/lutaml/xsd/xsd_bundler.rb +2 -2
  39. data/lib/lutaml/xsd/xsd_model_extensions.rb +66 -0
  40. data/lib/lutaml/xsd/xsd_spec_validator.rb +9 -13
  41. data/lib/lutaml/xsd.rb +1 -0
  42. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29e9ba5ed3edf116b76cdf22ed853a37399d00ffda6b11f78a0cccdb5502b4e4
4
- data.tar.gz: 6213f84485cad0ffed1eef19d60ae29fea7d5e274522ba8dfcc996048694e677
3
+ metadata.gz: 2753b7481b4a167c65a045225ccff7b4e42ebb73bdf767d89409ffedea3ec424
4
+ data.tar.gz: 9c242cbdacce62bd38fb1aace515f193200491ee4ab2cbbd46d45ffb54240fb0
5
5
  SHA512:
6
- metadata.gz: 07a2c5d774d76218e043372749950daa031c3b1ff3177a4eb65c5a05de6e6747479bbbd4acd7a5c7a808553bb75e62808d66bb68157324b4341d25045e11aa0b
7
- data.tar.gz: cba0111db7b0b7bf12fb9e0c55edbdfcbc4e3f4f11a653957ad663e6d8c067a1980bcbb7a54898f50b6e408869ca56d0179a822a7fcae8ba201111c68fceeb15
6
+ metadata.gz: b8806dcbb55c18a49ab961011f89f4533b6610894c9d991b67d3e55d7843ea08be3d46275b41995a318eb94734c11c70dfdeeb664c610ab2d52f6e9934376c3e
7
+ data.tar.gz: a65b3c52a32c4336c08afc45c8dd523a1b712e81909f6b3f507d80cacb9dc8fd0fb733cf0aa120c5d47484aa106aee82d5ad0b237a35170a58b98e8cc6e0ff8b
data/.gitignore CHANGED
@@ -29,3 +29,9 @@ frontend/dist/
29
29
  # Frontend index with mock data (should not be committed)
30
30
  frontend/index.html
31
31
 
32
+
33
+ # Transient build artifacts
34
+ *.gem
35
+ examples/*/pkg/
36
+ examples/*.html
37
+ examples/archive-old/
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-04-27 11:46:52 UTC using RuboCop version 1.86.1.
3
+ # on 2026-05-10 22:39:49 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,42 +11,71 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'lutaml-xsd.gemspec'
13
13
 
14
+ # Offense count: 12
15
+ # This cop supports safe autocorrection (--autocorrect).
16
+ # Configuration parameters: EnforcedStyle, IndentationWidth.
17
+ # SupportedStyles: with_first_argument, with_fixed_indentation
18
+ Layout/ArgumentAlignment:
19
+ Exclude:
20
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
21
+
14
22
  # Offense count: 1
15
23
  # This cop supports safe autocorrection (--autocorrect).
24
+ # Configuration parameters: IndentationWidth.
25
+ Layout/AssignmentIndentation:
26
+ Exclude:
27
+ - 'lib/lutaml/xsd/spa/schema_serializer.rb'
28
+
29
+ # Offense count: 3
30
+ # This cop supports safe autocorrection (--autocorrect).
16
31
  # Configuration parameters: EnforcedStyleAlignWith.
17
32
  # SupportedStylesAlignWith: either, start_of_block, start_of_line
18
33
  Layout/BlockAlignment:
19
34
  Exclude:
20
- - 'lib/lutaml/xsd/spa/schema_serializer.rb'
35
+ - 'lib/lutaml/xsd/errors/suggesters/fuzzy_matcher.rb'
36
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
21
37
 
22
38
  # Offense count: 1
23
39
  # This cop supports safe autocorrection (--autocorrect).
24
40
  Layout/BlockEndNewline:
25
41
  Exclude:
26
- - 'lib/lutaml/xsd/spa/schema_serializer.rb'
42
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
27
43
 
28
- # Offense count: 2
44
+ # Offense count: 16
45
+ # This cop supports safe autocorrection (--autocorrect).
46
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
47
+ # SupportedHashRocketStyles: key, separator, table
48
+ # SupportedColonStyles: key, separator, table
49
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
50
+ Layout/HashAlignment:
51
+ Exclude:
52
+ - 'lib/lutaml/xsd/xsd_model_extensions.rb'
53
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
54
+
55
+ # Offense count: 4
29
56
  # This cop supports safe autocorrection (--autocorrect).
30
57
  # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
31
58
  # SupportedStylesAlignWith: start_of_line, relative_to_receiver
32
59
  Layout/IndentationWidth:
33
60
  Exclude:
34
- - 'lib/lutaml/xsd/spa/schema_serializer.rb'
61
+ - 'lib/lutaml/xsd/errors/suggesters/fuzzy_matcher.rb'
62
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
35
63
 
36
- # Offense count: 722
64
+ # Offense count: 636
37
65
  # This cop supports safe autocorrection (--autocorrect).
38
66
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
39
67
  # URISchemes: http, https
40
68
  Layout/LineLength:
41
69
  Enabled: false
42
70
 
43
- # Offense count: 1
71
+ # Offense count: 11
44
72
  # This cop supports safe autocorrection (--autocorrect).
45
- # Configuration parameters: EnforcedStyle, IndentationWidth.
46
- # SupportedStyles: aligned, indented
47
- Layout/MultilineOperationIndentation:
73
+ # Configuration parameters: AllowInHeredoc.
74
+ Layout/TrailingWhitespace:
48
75
  Exclude:
49
76
  - 'lib/lutaml/xsd/spa/schema_serializer.rb'
77
+ - 'lib/lutaml/xsd/xsd_model_extensions.rb'
78
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
50
79
 
51
80
  # Offense count: 11
52
81
  # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
@@ -81,38 +110,38 @@ Lint/UselessRescue:
81
110
  Exclude:
82
111
  - 'lib/lutaml/xsd/validation/rule_engine.rb'
83
112
 
84
- # Offense count: 269
113
+ # Offense count: 264
85
114
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
86
115
  Metrics/AbcSize:
87
116
  Enabled: false
88
117
 
89
- # Offense count: 22
118
+ # Offense count: 21
90
119
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
91
120
  # AllowedMethods: refine
92
121
  Metrics/BlockLength:
93
122
  Max: 57
94
123
 
95
- # Offense count: 18
124
+ # Offense count: 16
96
125
  # Configuration parameters: CountBlocks, CountModifierForms.
97
126
  Metrics/BlockNesting:
98
127
  Max: 5
99
128
 
100
- # Offense count: 201
129
+ # Offense count: 175
101
130
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
102
131
  Metrics/CyclomaticComplexity:
103
132
  Enabled: false
104
133
 
105
- # Offense count: 373
134
+ # Offense count: 368
106
135
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
107
136
  Metrics/MethodLength:
108
137
  Max: 90
109
138
 
110
- # Offense count: 6
139
+ # Offense count: 7
111
140
  # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
112
141
  Metrics/ParameterLists:
113
142
  Max: 9
114
143
 
115
- # Offense count: 151
144
+ # Offense count: 134
116
145
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
117
146
  Metrics/PerceivedComplexity:
118
147
  Enabled: false
@@ -186,7 +215,7 @@ Security/MarshalLoad:
186
215
  # AllowedMethods: lambda, proc, it
187
216
  Style/BlockDelimiters:
188
217
  Exclude:
189
- - 'lib/lutaml/xsd/spa/schema_serializer.rb'
218
+ - 'spec/lutaml/xsd/spa/schema_serializer_spec.rb'
190
219
 
191
220
  # Offense count: 6
192
221
  Style/DocumentDynamicEvalDefinition:
@@ -214,6 +243,19 @@ Style/IdenticalConditionalBranches:
214
243
  Exclude:
215
244
  - 'lib/lutaml/xsd/package_tree_formatter.rb'
216
245
 
246
+ # Offense count: 2
247
+ # This cop supports unsafe autocorrection (--autocorrect-all).
248
+ Style/MapIntoArray:
249
+ Exclude:
250
+ - 'lib/lutaml/xsd/schema_repository.rb'
251
+ - 'lib/lutaml/xsd/xsd_spec_validator.rb'
252
+
253
+ # Offense count: 1
254
+ # This cop supports safe autocorrection (--autocorrect).
255
+ Style/MultilineIfModifier:
256
+ Exclude:
257
+ - 'lib/lutaml/xsd/spa/schema_serializer.rb'
258
+
217
259
  # Offense count: 1
218
260
  Style/OpenStructUse:
219
261
  Exclude:
@@ -226,9 +268,36 @@ Style/OptionalBooleanParameter:
226
268
  Exclude:
227
269
  - 'lib/lutaml/xsd/spa/output_mode.rb'
228
270
 
271
+ # Offense count: 2
272
+ # This cop supports safe autocorrection (--autocorrect).
273
+ # Configuration parameters: AllowedMethods.
274
+ # AllowedMethods: infinite?, nonzero?
275
+ Style/RedundantCondition:
276
+ Exclude:
277
+ - 'lib/lutaml/xsd/spa/schema_serializer.rb'
278
+ - 'lib/lutaml/xsd/validation/rules/content_model_validation_rule.rb'
279
+
280
+ # Offense count: 4
281
+ # This cop supports unsafe autocorrection (--autocorrect-all).
282
+ # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
283
+ # AllowedMethods: present?, blank?, presence, try, try!
284
+ Style/SafeNavigation:
285
+ Exclude:
286
+ - 'lib/lutaml/xsd/errors/suggesters/fuzzy_matcher.rb'
287
+ - 'lib/lutaml/xsd/spa/schema_serializer.rb'
288
+
229
289
  # Offense count: 2
230
290
  # This cop supports unsafe autocorrection (--autocorrect-all).
231
291
  # Configuration parameters: Mode.
232
292
  Style/StringConcatenation:
233
293
  Exclude:
234
294
  - 'lib/lutaml/xsd/validation/xml_navigator.rb'
295
+
296
+ # Offense count: 2
297
+ # This cop supports unsafe autocorrection (--autocorrect-all).
298
+ # Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
299
+ # AllowedMethods: define_method
300
+ Style/SymbolProc:
301
+ Exclude:
302
+ - 'lib/lutaml/xsd/schema_repository.rb'
303
+ - 'lib/lutaml/xsd/xsd_spec_validator.rb'
@@ -192,12 +192,12 @@ module Lutaml
192
192
  end
193
193
 
194
194
  def extract_element_type(element)
195
- return element.type if element.respond_to?(:type) && element.type
195
+ return element.type if element.type
196
196
 
197
197
  # If element has a complex or simple type definition
198
- if element.respond_to?(:complex_type) && element.complex_type
198
+ if element.complex_type
199
199
  "(inline complex type)"
200
- elsif element.respond_to?(:simple_type) && element.simple_type
200
+ elsif element.simple_type
201
201
  "(inline simple type)"
202
202
  else
203
203
  "(untyped)"
@@ -314,7 +314,7 @@ module Lutaml
314
314
  }
315
315
 
316
316
  # Extract type information
317
- if element.respond_to?(:type) && element.type
317
+ if element.type
318
318
  info[:type_ref] =
319
319
  element.type
320
320
  end
@@ -326,7 +326,7 @@ module Lutaml
326
326
  end
327
327
 
328
328
  # Extract documentation
329
- if element.respond_to?(:annotation) && element.annotation
329
+ if element.annotation
330
330
  info[:documentation] =
331
331
  extract_documentation(element.annotation)
332
332
  end
@@ -338,23 +338,23 @@ module Lutaml
338
338
  attrs = []
339
339
 
340
340
  # Direct attributes
341
- attrs.concat(Array(element.attribute)) if element.respond_to?(:attribute) && element.attribute
341
+ attrs.concat(Array(element.attribute)) if element.attribute.any?
342
342
 
343
343
  attrs.filter_map do |attr|
344
344
  {
345
- name: attr.respond_to?(:name) ? attr.name : nil,
346
- type: attr.respond_to?(:type) ? attr.type : nil,
347
- use: attr.respond_to?(:use) ? attr.use : nil,
345
+ name: attr.name,
346
+ type: attr.type,
347
+ use: attr.use,
348
348
  }
349
349
  end
350
350
  end
351
351
 
352
352
  def extract_documentation(annotation)
353
- docs = annotation.respond_to?(:documentation) ? annotation.documentation : nil
353
+ docs = annotation.documentation
354
354
  return nil unless docs
355
355
 
356
356
  Array(docs).filter_map do |doc|
357
- doc.respond_to?(:content) ? doc.content : doc.to_s
357
+ doc.content || doc.to_s
358
358
  end.join("\n").strip
359
359
  end
360
360
 
@@ -369,9 +369,9 @@ module Lutaml
369
369
 
370
370
  if info[:type_ref]
371
371
  output "Type Reference: #{info[:type_ref]}"
372
- elsif element.respond_to?(:complex_type) && element.complex_type
372
+ elsif element.complex_type
373
373
  output "Type: (inline complex type)"
374
- elsif element.respond_to?(:simple_type) && element.simple_type
374
+ elsif element.simple_type
375
375
  output "Type: (inline simple type)"
376
376
  end
377
377
 
@@ -436,7 +436,7 @@ module Lutaml
436
436
  return if depth > @max_depth
437
437
 
438
438
  connector = is_last ? "└── " : "├── "
439
- name = element.respond_to?(:name) ? element.name : "(unnamed)"
439
+ name = element.name || "(unnamed)"
440
440
  type_info = get_type_info(element)
441
441
 
442
442
  output "#{indent}#{connector}#{name}#{type_info}"
@@ -447,13 +447,13 @@ module Lutaml
447
447
  child_indent = indent + (is_last ? " " : "│ ")
448
448
 
449
449
  # Display child elements from complex type
450
- if element.respond_to?(:complex_type) && element.complex_type
450
+ if element.complex_type
451
451
  display_complex_type_children(element.complex_type, child_indent,
452
452
  depth, repository)
453
- elsif element.respond_to?(:type) && element.type
453
+ elsif element.type
454
454
  # Try to resolve the type reference
455
455
  type_result = repository.find_type(element.type)
456
- if type_result.resolved? && type_result.definition.respond_to?(:sequence)
456
+ if type_result.resolved? && type_result.definition.sequence
457
457
  display_sequence_children(type_result.definition.sequence, child_indent, depth,
458
458
  repository)
459
459
  end
@@ -461,11 +461,11 @@ module Lutaml
461
461
  end
462
462
 
463
463
  def get_type_info(element)
464
- if element.respond_to?(:type) && element.type
464
+ if element.type
465
465
  " : #{element.type}"
466
- elsif element.respond_to?(:complex_type) && element.complex_type
466
+ elsif element.complex_type
467
467
  " : (complex type)"
468
- elsif element.respond_to?(:simple_type) && element.simple_type
468
+ elsif element.simple_type
469
469
  " : (simple type)"
470
470
  else
471
471
  ""
@@ -475,20 +475,20 @@ module Lutaml
475
475
  def display_complex_type_children(complex_type, indent, depth,
476
476
  repository)
477
477
  # Display sequence elements
478
- if complex_type.respond_to?(:sequence) && complex_type.sequence
478
+ if complex_type.sequence
479
479
  display_sequence_children(complex_type.sequence, indent, depth,
480
480
  repository)
481
481
  end
482
482
 
483
483
  # Display choice elements
484
- return unless complex_type.respond_to?(:choice) && complex_type.choice
484
+ return unless complex_type.choice
485
485
 
486
486
  display_choice_children(complex_type.choice, indent, depth,
487
487
  repository)
488
488
  end
489
489
 
490
490
  def display_sequence_children(sequence, indent, depth, repository)
491
- elements = sequence.respond_to?(:element) ? Array(sequence.element).compact : []
491
+ elements = Array(sequence.element).compact
492
492
  return if elements.empty?
493
493
 
494
494
  elements.each_with_index do |elem, idx|
@@ -498,7 +498,7 @@ repository)
498
498
  end
499
499
 
500
500
  def display_choice_children(choice, indent, depth, repository)
501
- elements = choice.respond_to?(:element) ? Array(choice.element).compact : []
501
+ elements = Array(choice.element).compact
502
502
  return if elements.empty?
503
503
 
504
504
  output "#{indent}└── (choice)"
@@ -184,11 +184,11 @@ module Lutaml
184
184
  namespaces.map do |uri|
185
185
  data = {
186
186
  uri: uri,
187
- prefix: repository.send(:namespace_to_prefix, uri),
187
+ prefix: repository.namespace_to_prefix(uri),
188
188
  }
189
189
 
190
190
  if options[:show_counts]
191
- types = repository.send(:types_in_namespace, uri)
191
+ types = repository.types_in_namespace(uri)
192
192
  data[:type_count] = types.size
193
193
  data[:types_by_category] = count_types_by_category(types)
194
194
  end
@@ -282,13 +282,13 @@ module Lutaml
282
282
  end
283
283
 
284
284
  def build_namespace_info(repository)
285
- types = repository.send(:types_in_namespace, @namespace_uri)
285
+ types = repository.types_in_namespace(@namespace_uri)
286
286
  types_by_category = Hash.new(0)
287
287
  types.each { |type_info| types_by_category[type_info[:type]] += 1 }
288
288
 
289
289
  info = {
290
290
  uri: @namespace_uri,
291
- prefix: repository.send(:namespace_to_prefix, @namespace_uri),
291
+ prefix: repository.namespace_to_prefix(@namespace_uri),
292
292
  total_types: types.size,
293
293
  types_by_category: types_by_category,
294
294
  }
@@ -402,10 +402,10 @@ module Lutaml
402
402
 
403
403
  def build_tree_data(repository, namespaces)
404
404
  tree_data = namespaces.map do |uri|
405
- types = repository.send(:types_in_namespace, uri)
405
+ types = repository.types_in_namespace(uri)
406
406
  {
407
407
  uri: uri,
408
- prefix: repository.send(:namespace_to_prefix, uri),
408
+ prefix: repository.namespace_to_prefix(uri),
409
409
  type_count: types.size,
410
410
  types_by_category: count_types_by_category(types),
411
411
  }
@@ -327,55 +327,55 @@ module Lutaml
327
327
 
328
328
  def display_type_structure(definition, repository)
329
329
  # Display simple content
330
- if definition.respond_to?(:simple_content) && definition.simple_content
330
+ if definition.simple_content
331
331
  display_simple_content(definition.simple_content,
332
332
  repository)
333
333
  end
334
334
 
335
335
  # Display complex content
336
- if definition.respond_to?(:complex_content) && definition.complex_content
336
+ if definition.complex_content
337
337
  display_complex_content(definition.complex_content,
338
338
  repository)
339
339
  end
340
340
 
341
341
  # Display sequence elements
342
- if definition.respond_to?(:sequence) && definition.sequence
342
+ if definition.sequence
343
343
  display_sequence(definition.sequence,
344
344
  repository)
345
345
  end
346
346
 
347
347
  # Display choice elements
348
- if definition.respond_to?(:choice) && definition.choice
348
+ if definition.choice
349
349
  display_choice(definition.choice,
350
350
  repository)
351
351
  end
352
352
 
353
353
  # Display all elements
354
- if definition.respond_to?(:all) && definition.all
354
+ if definition.all
355
355
  display_all(definition.all,
356
356
  repository)
357
357
  end
358
358
 
359
359
  # Display direct attributes
360
- if definition.respond_to?(:attribute) && definition.attribute
360
+ if definition.attribute
361
361
  display_attributes(definition.attribute, repository,
362
362
  "Attributes")
363
363
  end
364
364
 
365
365
  # Display attribute groups
366
- display_attribute_groups(definition.attribute_group) if definition.respond_to?(:attribute_group) && definition.attribute_group
366
+ display_attribute_groups(definition.attribute_group) if definition.attribute_group
367
367
  end
368
368
 
369
369
  def display_simple_content(simple_content, repository)
370
370
  output "Simple Content:"
371
371
 
372
- return unless simple_content.respond_to?(:extension) && simple_content.extension
372
+ return unless simple_content.extension
373
373
 
374
374
  extension = simple_content.extension
375
375
  output " Extension:"
376
- output " Base: #{extension.base}" if extension.respond_to?(:base)
376
+ output " Base: #{extension.base}" if extension.base
377
377
 
378
- return unless extension.respond_to?(:attribute) && extension.attribute
378
+ return unless extension.attribute
379
379
 
380
380
  display_attributes(extension.attribute, repository,
381
381
  " Attributes", indent: " ")
@@ -384,44 +384,44 @@ module Lutaml
384
384
  def display_complex_content(complex_content, repository)
385
385
  output "Complex Content:"
386
386
 
387
- if complex_content.respond_to?(:extension) && complex_content.extension
387
+ if complex_content.extension
388
388
  extension = complex_content.extension
389
389
  output " Extension:"
390
- output " Base: #{extension.base}" if extension.respond_to?(:base)
390
+ output " Base: #{extension.base}" if extension.base
391
391
 
392
392
  # Display sequence from extension
393
- if extension.respond_to?(:sequence) && extension.sequence
393
+ if extension.sequence
394
394
  display_sequence(extension.sequence, repository,
395
395
  indent: " ")
396
396
  end
397
397
 
398
398
  # Display attributes from extension
399
- if extension.respond_to?(:attribute) && extension.attribute
399
+ if extension.attribute
400
400
  display_attributes(extension.attribute, repository, " Attributes",
401
401
  indent: " ")
402
402
  end
403
403
 
404
404
  # Display attribute groups from extension
405
- if extension.respond_to?(:attribute_group) && extension.attribute_group
405
+ if extension.attribute_group
406
406
  display_attribute_groups(extension.attribute_group,
407
407
  indent: " ")
408
408
  end
409
409
  end
410
410
 
411
- return unless complex_content.respond_to?(:restriction) && complex_content.restriction
411
+ return unless complex_content.restriction
412
412
 
413
413
  restriction = complex_content.restriction
414
414
  output " Restriction:"
415
- output " Base: #{restriction.base}" if restriction.respond_to?(:base)
415
+ output " Base: #{restriction.base}" if restriction.base
416
416
 
417
417
  # Display sequence from restriction
418
- if restriction.respond_to?(:sequence) && restriction.sequence
418
+ if restriction.sequence
419
419
  display_sequence(restriction.sequence, repository,
420
420
  indent: " ")
421
421
  end
422
422
 
423
423
  # Display attributes from restriction
424
- return unless restriction.respond_to?(:attribute) && restriction.attribute
424
+ return unless restriction.attribute
425
425
 
426
426
  display_attributes(restriction.attribute, repository, " Attributes",
427
427
  indent: " ")
@@ -693,7 +693,7 @@ indent: "")
693
693
  return nil unless parsed_schemas
694
694
 
695
695
  parsed_schemas.each_value do |schema|
696
- next unless schema.respond_to?(:attribute)
696
+ next if schema.attribute.empty?
697
697
 
698
698
  attrs = schema.attribute
699
699
  attrs = [attrs] unless attrs.is_a?(Array)
@@ -758,7 +758,7 @@ indent: "")
758
758
  return nil unless parsed_schemas
759
759
 
760
760
  parsed_schemas.each_value do |schema|
761
- next unless schema.respond_to?(:element)
761
+ next if schema.element.empty?
762
762
 
763
763
  elements = schema.element
764
764
  elements = [elements] unless elements.is_a?(Array)
@@ -803,7 +803,7 @@ indent: "")
803
803
  docs = [docs] unless docs.is_a?(Array)
804
804
 
805
805
  docs.filter_map do |doc|
806
- content = doc.respond_to?(:content) ? doc.content : doc.to_s
806
+ content = doc.content || doc.to_s
807
807
  content&.strip
808
808
  end.first || ""
809
809
  end
@@ -816,7 +816,7 @@ indent: "")
816
816
  hints = []
817
817
 
818
818
  # Collect hints from sequence elements
819
- if definition.respond_to?(:sequence) && definition.sequence
819
+ if definition.sequence
820
820
  definition.sequence.element.first(3).each do |elem|
821
821
  ref = elem.ref || elem.name
822
822
  type = nil
@@ -827,7 +827,7 @@ indent: "")
827
827
  elsif elem.ref
828
828
  # Look up the referenced element to get its type
829
829
  elem_def = repository.find_element(elem.ref)
830
- type = elem_def.type if elem_def.respond_to?(:type)
830
+ type = elem_def.type if elem_def.type
831
831
  end
832
832
 
833
833
  next if !type || type == "(inline)" || type =~ /^xsd?:/
@@ -841,7 +841,7 @@ indent: "")
841
841
  end
842
842
 
843
843
  # Collect hints from choice elements
844
- if definition.respond_to?(:choice) && definition.choice
844
+ if definition.choice
845
845
  definition.choice.element.first(3).each do |elem|
846
846
  ref = elem.ref || elem.name
847
847
  type = nil
@@ -852,7 +852,7 @@ indent: "")
852
852
  elsif elem.ref
853
853
  # Look up the referenced element to get its type
854
854
  elem_def = repository.find_element(elem.ref)
855
- type = elem_def.type if elem_def.respond_to?(:type)
855
+ type = elem_def.type if elem_def.type
856
856
  end
857
857
 
858
858
  next if !type || type == "(inline)" || type =~ /^xsd?:/
@@ -866,9 +866,9 @@ indent: "")
866
866
  end
867
867
 
868
868
  # Collect hints from complex content extensions
869
- if definition.respond_to?(:complex_content) && definition.complex_content.respond_to?(:extension) && definition.complex_content.extension
869
+ if definition.complex_content&.extension
870
870
  extension = definition.complex_content.extension
871
- if extension.respond_to?(:base) && extension.base && extension.base !~ /^xsd?:/
871
+ if extension.base && extension.base !~ /^xsd?:/
872
872
  hints << {
873
873
  element: "base type",
874
874
  type: extension.base,
@@ -877,7 +877,7 @@ indent: "")
877
877
  end
878
878
 
879
879
  # Also check sequence in extension
880
- if extension.respond_to?(:sequence) && extension.sequence
880
+ if extension.sequence
881
881
  extension.sequence.element.first(2).each do |elem|
882
882
  ref = elem.ref || elem.name
883
883
  type = elem.type || "(inline)"
@@ -893,9 +893,9 @@ indent: "")
893
893
  end
894
894
 
895
895
  # Collect hints from simple content extensions
896
- if definition.respond_to?(:simple_content) && definition.simple_content.respond_to?(:extension) && definition.simple_content.extension
896
+ if definition.simple_content&.extension
897
897
  extension = definition.simple_content.extension
898
- if extension.respond_to?(:base) && extension.base && extension.base !~ /^xsd?:/
898
+ if extension.base && extension.base !~ /^xsd?:/
899
899
  hints << {
900
900
  element: "base type",
901
901
  type: extension.base,