lutaml-xsd 1.0.7 → 1.0.8
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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +37 -3
- data/docs/FAQ.adoc +1 -1
- data/docs/URL_FETCHING.adoc +5 -6
- data/docs/advanced/INTEGRATION_PATTERNS.adoc +10 -11
- data/docs/advanced/SCHEMA_MAPPING_PATTERNS.adoc +4 -3
- data/examples/02-urban-function/scripts/map_uro_types.rb +4 -3
- data/lib/lutaml/xsd/commands/package_command.rb +4 -1
- data/lib/lutaml/xsd/definition_extractor.rb +6 -7
- data/lib/lutaml/xsd/package_builder.rb +39 -0
- data/lib/lutaml/xsd/spa/schema_serializer.rb +43 -25
- data/lib/lutaml/xsd/spa/utils/extract_enumeration.rb +4 -1
- data/lib/lutaml/xsd/spa/xml_instance_generator.rb +1 -1
- data/lib/lutaml/xsd/validation/xml_navigator.rb +3 -3
- data/lib/lutaml/xsd/version.rb +1 -1
- data/lib/lutaml/xsd.rb +0 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6278aec90450f0666ccb21d61f3afa2f7f77be209dac10da32c991841a31a7d
|
|
4
|
+
data.tar.gz: 5dc436d5d5e8323fec4bd2fe2928f0890de032e626d0f4bde19baf5570acaccb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5491e6d47a6d39bbb0ff66ab75334aaafebfbc171de6117bfd9b5fae07badea0d53239941c1539d3d67c6e49dfda736e6420b489036a56529affca0f89431e17
|
|
7
|
+
data.tar.gz: 2e020487a42d0c3eaf86ad45040719632178147891edf4b35caa6d7d9d1fad310ed9682f4a5c70627429078d2db472997aa691e7da7f19e1d355b816afea0444
|
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-
|
|
3
|
+
# on 2026-04-25 09:44:01 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,6 +11,29 @@ Gemspec/RequiredRubyVersion:
|
|
|
11
11
|
Exclude:
|
|
12
12
|
- 'lutaml-xsd.gemspec'
|
|
13
13
|
|
|
14
|
+
# Offense count: 2
|
|
15
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
16
|
+
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
17
|
+
# SupportedStyles: with_first_element, with_fixed_indentation
|
|
18
|
+
Layout/ArrayAlignment:
|
|
19
|
+
Exclude:
|
|
20
|
+
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
21
|
+
- 'lib/lutaml/xsd/spa/utils/extract_enumeration.rb'
|
|
22
|
+
|
|
23
|
+
# Offense count: 4
|
|
24
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
25
|
+
# Configuration parameters: IndentationWidth.
|
|
26
|
+
Layout/AssignmentIndentation:
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'lib/lutaml/xsd/commands/package_command.rb'
|
|
29
|
+
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
30
|
+
|
|
31
|
+
# Offense count: 7
|
|
32
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
33
|
+
Layout/ClosingParenthesisIndentation:
|
|
34
|
+
Exclude:
|
|
35
|
+
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
36
|
+
|
|
14
37
|
# Offense count: 1
|
|
15
38
|
# This cop supports safe autocorrection (--autocorrect).
|
|
16
39
|
# Configuration parameters: EnforcedStyleAlignWith.
|
|
@@ -45,7 +68,7 @@ Layout/IndentationWidth:
|
|
|
45
68
|
Exclude:
|
|
46
69
|
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
47
70
|
|
|
48
|
-
# Offense count:
|
|
71
|
+
# Offense count: 730
|
|
49
72
|
# This cop supports safe autocorrection (--autocorrect).
|
|
50
73
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
51
74
|
# URISchemes: http, https
|
|
@@ -60,11 +83,14 @@ Layout/MultilineMethodCallBraceLayout:
|
|
|
60
83
|
Exclude:
|
|
61
84
|
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
62
85
|
|
|
63
|
-
# Offense count:
|
|
86
|
+
# Offense count: 11
|
|
64
87
|
# This cop supports safe autocorrection (--autocorrect).
|
|
65
88
|
# Configuration parameters: AllowInHeredoc.
|
|
66
89
|
Layout/TrailingWhitespace:
|
|
67
90
|
Exclude:
|
|
91
|
+
- 'lib/lutaml/xsd/commands/package_command.rb'
|
|
92
|
+
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
93
|
+
- 'lib/lutaml/xsd/spa/utils/extract_enumeration.rb'
|
|
68
94
|
- 'lib/lutaml/xsd/spa/xml_instance_generator.rb'
|
|
69
95
|
|
|
70
96
|
# Offense count: 11
|
|
@@ -222,6 +248,14 @@ Style/IdenticalConditionalBranches:
|
|
|
222
248
|
Exclude:
|
|
223
249
|
- 'lib/lutaml/xsd/package_tree_formatter.rb'
|
|
224
250
|
|
|
251
|
+
# Offense count: 3
|
|
252
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
253
|
+
Style/MultilineIfModifier:
|
|
254
|
+
Exclude:
|
|
255
|
+
- 'lib/lutaml/xsd/commands/package_command.rb'
|
|
256
|
+
- 'lib/lutaml/xsd/spa/schema_serializer.rb'
|
|
257
|
+
- 'lib/lutaml/xsd/spa/utils/extract_enumeration.rb'
|
|
258
|
+
|
|
225
259
|
# Offense count: 1
|
|
226
260
|
Style/OpenStructUse:
|
|
227
261
|
Exclude:
|
data/docs/FAQ.adoc
CHANGED
|
@@ -457,7 +457,7 @@ Note: `marshal` format packages may not be compatible across different Ruby majo
|
|
|
457
457
|
|
|
458
458
|
Yes! Lutaml::XSD is complementary to other XML tools:
|
|
459
459
|
|
|
460
|
-
* **
|
|
460
|
+
* **Moxml**: Unified XML adapter layer
|
|
461
461
|
* **REXML**: Use for lightweight XML processing
|
|
462
462
|
* **Ox**: Use for fast XML parsing
|
|
463
463
|
|
data/docs/URL_FETCHING.adoc
CHANGED
|
@@ -603,12 +603,11 @@ Validate schema content after fetching:
|
|
|
603
603
|
====
|
|
604
604
|
[source,ruby]
|
|
605
605
|
----
|
|
606
|
-
require '
|
|
606
|
+
require 'moxml'
|
|
607
607
|
|
|
608
608
|
def validate_schema_content(content)
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
end
|
|
609
|
+
ctx = Moxml::Context.new
|
|
610
|
+
doc = ctx.parse(content)
|
|
612
611
|
|
|
613
612
|
# Validate it's actually an XSD schema
|
|
614
613
|
unless doc.root&.name == 'schema' &&
|
|
@@ -617,12 +616,12 @@ def validate_schema_content(content)
|
|
|
617
616
|
end
|
|
618
617
|
|
|
619
618
|
# Check for suspicious patterns
|
|
620
|
-
if doc.
|
|
619
|
+
if doc.to_xml.match?(/<!ENTITY|<!DOCTYPE/)
|
|
621
620
|
raise SecurityError, "Schema contains potentially dangerous XML entities"
|
|
622
621
|
end
|
|
623
622
|
|
|
624
623
|
content
|
|
625
|
-
rescue
|
|
624
|
+
rescue StandardError => e
|
|
626
625
|
raise SecurityError, "Schema failed XML validation: #{e.message}"
|
|
627
626
|
end
|
|
628
627
|
----
|
|
@@ -466,13 +466,13 @@ generator.generate('docs/api')
|
|
|
466
466
|
|
|
467
467
|
=== Integrating with XML validators
|
|
468
468
|
|
|
469
|
-
.Using Lutaml::XSD with
|
|
469
|
+
.Using Lutaml::XSD with XML validation
|
|
470
470
|
[example]
|
|
471
471
|
====
|
|
472
472
|
[source,ruby]
|
|
473
473
|
----
|
|
474
474
|
require 'lutaml/xsd'
|
|
475
|
-
require '
|
|
475
|
+
require 'moxml'
|
|
476
476
|
|
|
477
477
|
class SchemaValidator
|
|
478
478
|
def initialize(lxr_package_path)
|
|
@@ -488,14 +488,13 @@ class SchemaValidator
|
|
|
488
488
|
xsd_file = result.schema_file
|
|
489
489
|
xsd_content = load_xsd_content(xsd_file)
|
|
490
490
|
|
|
491
|
-
#
|
|
492
|
-
|
|
491
|
+
# Parse XML document using Moxml
|
|
492
|
+
ctx = Moxml::Context.new
|
|
493
|
+
doc = ctx.parse(xml_content)
|
|
493
494
|
|
|
494
|
-
#
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
# Validate
|
|
498
|
-
errors = xsd.validate(doc)
|
|
495
|
+
# Validate against XSD schema
|
|
496
|
+
# (Use a dedicated XSD validation library for full schema validation)
|
|
497
|
+
errors = []
|
|
499
498
|
|
|
500
499
|
{
|
|
501
500
|
valid: errors.empty?,
|
|
@@ -538,7 +537,7 @@ end
|
|
|
538
537
|
[source,ruby]
|
|
539
538
|
----
|
|
540
539
|
require 'lutaml/xsd'
|
|
541
|
-
require '
|
|
540
|
+
require 'moxml'
|
|
542
541
|
|
|
543
542
|
class ValidationPipeline
|
|
544
543
|
def initialize(schemas_package)
|
|
@@ -1031,7 +1030,7 @@ manager.deploy(:production, '/var/app/schemas.lxr')
|
|
|
1031
1030
|
----
|
|
1032
1031
|
require 'lutaml/xsd'
|
|
1033
1032
|
require 'liquid'
|
|
1034
|
-
require '
|
|
1033
|
+
require 'moxml'
|
|
1035
1034
|
|
|
1036
1035
|
class SchemaWorkflow
|
|
1037
1036
|
def initialize(config_file)
|
|
@@ -702,18 +702,19 @@ end
|
|
|
702
702
|
[source,ruby]
|
|
703
703
|
----
|
|
704
704
|
require 'lutaml/xsd'
|
|
705
|
-
require '
|
|
705
|
+
require 'moxml'
|
|
706
706
|
require 'yaml'
|
|
707
707
|
|
|
708
708
|
def extract_imports_and_includes(xsd_file)
|
|
709
|
-
|
|
709
|
+
ctx = Moxml::Context.new
|
|
710
|
+
doc = ctx.parse(File.read(xsd_file))
|
|
710
711
|
|
|
711
712
|
imports = doc.xpath('//xs:import/@schemaLocation',
|
|
712
713
|
'xs' => 'http://www.w3.org/2001/XMLSchema')
|
|
713
714
|
includes = doc.xpath('//xs:include/@schemaLocation',
|
|
714
715
|
'xs' => 'http://www.w3.org/2001/XMLSchema')
|
|
715
716
|
|
|
716
|
-
(imports + includes).map(
|
|
717
|
+
(imports + includes).map { |attr| attr.is_a?(Moxml::Attribute) ? attr.value : attr.text }.uniq
|
|
717
718
|
end
|
|
718
719
|
|
|
719
720
|
def suggest_mapping(schema_location)
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "moxml"
|
|
4
4
|
require "yaml"
|
|
5
5
|
|
|
6
6
|
# Parse both XSD files
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
ctx = Moxml::Context.new
|
|
8
|
+
urban_function_doc = ctx.parse(File.read("schemas/urbanFunction.xsd"))
|
|
9
|
+
urban_object_doc = ctx.parse(File.read("schemas/urbanObject.xsd"))
|
|
9
10
|
|
|
10
11
|
# Define namespaces
|
|
11
12
|
namespaces = {
|
|
@@ -524,7 +524,10 @@ module Lutaml
|
|
|
524
524
|
metadata[:appearance] =
|
|
525
525
|
full_config["appearance"]
|
|
526
526
|
end
|
|
527
|
-
|
|
527
|
+
if metadata_config["links"]
|
|
528
|
+
metadata[:links] =
|
|
529
|
+
metadata_config["links"]
|
|
530
|
+
end
|
|
528
531
|
metadata
|
|
529
532
|
end
|
|
530
533
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "moxml"
|
|
4
4
|
|
|
5
5
|
module Lutaml
|
|
6
6
|
module Xsd
|
|
@@ -183,7 +183,7 @@ module Lutaml
|
|
|
183
183
|
return nil unless File.exist?(schema_file)
|
|
184
184
|
|
|
185
185
|
content = File.read(schema_file)
|
|
186
|
-
doc =
|
|
186
|
+
doc = Moxml::Context.new.parse(content)
|
|
187
187
|
|
|
188
188
|
# Find the definition node
|
|
189
189
|
definition_node = find_definition_node(doc, name, type)
|
|
@@ -204,10 +204,10 @@ module Lutaml
|
|
|
204
204
|
end
|
|
205
205
|
|
|
206
206
|
# Find definition node in XML document
|
|
207
|
-
# @param node [
|
|
207
|
+
# @param node [Moxml::Document] XML document to search
|
|
208
208
|
# @param name [String] Name to find
|
|
209
209
|
# @param type [String] Type of definition
|
|
210
|
-
# @return [
|
|
210
|
+
# @return [Moxml::Element, nil] Found node or nil
|
|
211
211
|
def find_definition_node(node, name, type)
|
|
212
212
|
# Use XPath to find the definition
|
|
213
213
|
xpath = case type.downcase
|
|
@@ -227,11 +227,10 @@ module Lutaml
|
|
|
227
227
|
end
|
|
228
228
|
|
|
229
229
|
# Extract XML from node as string
|
|
230
|
-
# @param node [
|
|
230
|
+
# @param node [Moxml::Element] XML node
|
|
231
231
|
# @return [String] XML string
|
|
232
232
|
def extract_node_xml(node)
|
|
233
|
-
|
|
234
|
-
node.to_xml(indent: 2)
|
|
233
|
+
node.to_xml
|
|
235
234
|
rescue StandardError
|
|
236
235
|
"<Could not extract XSD source>"
|
|
237
236
|
end
|
|
@@ -64,6 +64,12 @@ module Lutaml
|
|
|
64
64
|
def serialize_schema(schema, format)
|
|
65
65
|
case format
|
|
66
66
|
when :marshal
|
|
67
|
+
# Clear lazy XML element references that hold non-serializable
|
|
68
|
+
# adapter nodes throughout the object graph.
|
|
69
|
+
# lutaml-model's :lazy import_declaration_plan mode stores
|
|
70
|
+
# XmlElement references (containing Nokogiri nodes) on every
|
|
71
|
+
# model instance during deserialization.
|
|
72
|
+
clear_pending_plan_references(schema)
|
|
67
73
|
Marshal.dump(schema)
|
|
68
74
|
when :json
|
|
69
75
|
schema.to_json
|
|
@@ -193,6 +199,39 @@ module Lutaml
|
|
|
193
199
|
|
|
194
200
|
private
|
|
195
201
|
|
|
202
|
+
# Recursively walk an object graph and clear pending_plan_root_element
|
|
203
|
+
# on every Lutaml::Model::Serializable instance. This removes Nokogiri
|
|
204
|
+
# adapter_node references that prevent Marshal.dump from succeeding.
|
|
205
|
+
#
|
|
206
|
+
# @param root [Object] Root of the object graph to walk
|
|
207
|
+
# @param visited [Set] Track visited object IDs to prevent infinite loops
|
|
208
|
+
def clear_pending_plan_references(root, visited = Set.new)
|
|
209
|
+
return unless root
|
|
210
|
+
return if visited.include?(root.object_id)
|
|
211
|
+
|
|
212
|
+
visited << root.object_id
|
|
213
|
+
|
|
214
|
+
case root
|
|
215
|
+
when Array
|
|
216
|
+
root.each { |item| clear_pending_plan_references(item, visited) }
|
|
217
|
+
when Hash
|
|
218
|
+
root.each_value { |v| clear_pending_plan_references(v, visited) }
|
|
219
|
+
else
|
|
220
|
+
if root.respond_to?(:pending_plan_root_element=)
|
|
221
|
+
root.pending_plan_root_element = nil
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
root.instance_variables.each do |ivar|
|
|
225
|
+
value = root.instance_variable_get(ivar)
|
|
226
|
+
next if value.nil? || value.is_a?(Symbol) ||
|
|
227
|
+
value.is_a?(Integer) || value.is_a?(Float) ||
|
|
228
|
+
value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
|
229
|
+
|
|
230
|
+
clear_pending_plan_references(value, visited)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
196
235
|
# Build metadata with package configuration
|
|
197
236
|
# @param repository [SchemaRepository] Repository to package
|
|
198
237
|
# @param additional [Hash] Additional metadata fields
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
+
require "moxml"
|
|
4
5
|
require "tmpdir"
|
|
5
6
|
require "fileutils"
|
|
6
7
|
require_relative "xml_instance_generator"
|
|
@@ -184,7 +185,8 @@ module Lutaml
|
|
|
184
185
|
# Detect standard XML Schema namespace using parsed URI components
|
|
185
186
|
begin
|
|
186
187
|
uri = URI(ns)
|
|
187
|
-
if uri&.host && %w[w3.org
|
|
188
|
+
if uri&.host && %w[w3.org
|
|
189
|
+
www.w3.org].include?(uri.host) && uri.path&.include?("XMLSchema")
|
|
188
190
|
return "xs"
|
|
189
191
|
end
|
|
190
192
|
rescue URI::InvalidURIError
|
|
@@ -230,12 +232,12 @@ module Lutaml
|
|
|
230
232
|
return nil unless schema
|
|
231
233
|
|
|
232
234
|
schema_source = if file_path
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
begin
|
|
236
|
+
File.read(file_path)
|
|
237
|
+
rescue StandardError
|
|
238
|
+
nil
|
|
239
|
+
end
|
|
240
|
+
end
|
|
239
241
|
|
|
240
242
|
prefix = namespace_prefix_lookup[schema.target_namespace] || derive_prefix(
|
|
241
243
|
schema.target_namespace, schema
|
|
@@ -248,14 +250,17 @@ module Lutaml
|
|
|
248
250
|
file_path: clean_file_path(file_path),
|
|
249
251
|
is_entrypoint: is_entrypoint?(file_path),
|
|
250
252
|
elements: serialize_elements(
|
|
251
|
-
schema, prefix, schema_source, file_path
|
|
253
|
+
schema, prefix, schema_source, file_path
|
|
254
|
+
),
|
|
252
255
|
complex_types: serialize_complex_types(
|
|
253
|
-
schema, prefix, schema_source, file_path
|
|
256
|
+
schema, prefix, schema_source, file_path
|
|
257
|
+
),
|
|
254
258
|
simple_types: serialize_simple_types(schema, prefix),
|
|
255
259
|
attributes: serialize_attributes(schema, prefix),
|
|
256
260
|
groups: serialize_groups(schema, prefix),
|
|
257
261
|
attribute_groups: serialize_attribute_groups(
|
|
258
|
-
schema, prefix, schema_source
|
|
262
|
+
schema, prefix, schema_source
|
|
263
|
+
),
|
|
259
264
|
imports: serialize_imports(schema),
|
|
260
265
|
includes: serialize_includes(schema),
|
|
261
266
|
}
|
|
@@ -314,7 +319,8 @@ module Lutaml
|
|
|
314
319
|
documentation: extract_documentation(element),
|
|
315
320
|
instance_xml: generate_instance_xml(element),
|
|
316
321
|
source: extract_source_by_type_key_value(
|
|
317
|
-
"element", "name", element.name, prefix, schema_source
|
|
322
|
+
"element", "name", element.name, prefix, schema_source
|
|
323
|
+
),
|
|
318
324
|
}
|
|
319
325
|
|
|
320
326
|
# Enriched fields
|
|
@@ -343,7 +349,8 @@ module Lutaml
|
|
|
343
349
|
end
|
|
344
350
|
|
|
345
351
|
# Add SVG diagram
|
|
346
|
-
element_data[:diagram_svg] =
|
|
352
|
+
element_data[:diagram_svg] =
|
|
353
|
+
generate_diagram(element_data, :element, file_path)
|
|
347
354
|
|
|
348
355
|
element_data
|
|
349
356
|
end
|
|
@@ -387,13 +394,15 @@ module Lutaml
|
|
|
387
394
|
# @param prefix [String, nil] Optional prefix for IDs
|
|
388
395
|
# @param schema_source [String, nil] Optional schema source for context
|
|
389
396
|
# @return [Array<Hash>] Serialized complex types (sorted alphabetically by name)
|
|
390
|
-
def serialize_complex_types(schema, prefix = nil, schema_source = nil,
|
|
397
|
+
def serialize_complex_types(schema, prefix = nil, schema_source = nil,
|
|
398
|
+
file_path = nil)
|
|
391
399
|
return [] unless schema.respond_to?(:complex_types) || schema.respond_to?(:complex_type)
|
|
392
400
|
|
|
393
401
|
types = schema.respond_to?(:complex_types) ? schema.complex_types : schema.complex_type
|
|
394
402
|
types.map.with_index do |type, index|
|
|
395
403
|
serialize_complex_type(
|
|
396
|
-
type, index, prefix, schema_source, file_path
|
|
404
|
+
type, index, prefix, schema_source, file_path
|
|
405
|
+
)
|
|
397
406
|
end.sort_by { |t| t[:name] || "" }
|
|
398
407
|
end
|
|
399
408
|
|
|
@@ -402,7 +411,8 @@ module Lutaml
|
|
|
402
411
|
# @param type [ComplexType] Complex type object
|
|
403
412
|
# @param index [Integer] Type index
|
|
404
413
|
# @return [Hash] Serialized complex type
|
|
405
|
-
def serialize_complex_type(type, index, prefix = nil,
|
|
414
|
+
def serialize_complex_type(type, index, prefix = nil,
|
|
415
|
+
schema_source = nil, file_path = nil)
|
|
406
416
|
content_model = extract_content_model(type)
|
|
407
417
|
type_data = {
|
|
408
418
|
id: complex_type_id(index, type, prefix),
|
|
@@ -418,15 +428,20 @@ module Lutaml
|
|
|
418
428
|
documentation: extract_documentation(type),
|
|
419
429
|
instance_xml: generate_instance_xml(type),
|
|
420
430
|
source: extract_source_by_type_key_value(
|
|
421
|
-
|
|
431
|
+
"complexType", "name", type.name, prefix, schema_source
|
|
432
|
+
),
|
|
422
433
|
}
|
|
423
434
|
|
|
424
435
|
# Collect attributes from inside extension for simpleContent/complexContent
|
|
425
436
|
extension_attrs = collect_extension_attributes(type)
|
|
426
|
-
|
|
437
|
+
unless extension_attrs.empty?
|
|
438
|
+
type_data[:extension_attributes] =
|
|
439
|
+
extension_attrs
|
|
440
|
+
end
|
|
427
441
|
|
|
428
442
|
# Add SVG diagram
|
|
429
|
-
type_data[:diagram_svg] =
|
|
443
|
+
type_data[:diagram_svg] =
|
|
444
|
+
generate_diagram(type_data, :type, file_path)
|
|
430
445
|
|
|
431
446
|
type_data
|
|
432
447
|
end
|
|
@@ -601,7 +616,8 @@ module Lutaml
|
|
|
601
616
|
# @param prefix [String, nil] Optional prefix for IDs
|
|
602
617
|
# @param schema_source [String, nil] Optional schema source for context
|
|
603
618
|
# @return [Array<Hash>] Serialized attribute groups (sorted alphabetically by name)
|
|
604
|
-
def serialize_attribute_groups(schema, prefix = nil,
|
|
619
|
+
def serialize_attribute_groups(schema, prefix = nil,
|
|
620
|
+
schema_source = nil)
|
|
605
621
|
groups = if schema.respond_to?(:attribute_groups)
|
|
606
622
|
schema.attribute_groups
|
|
607
623
|
elsif schema.respond_to?(:attribute_group)
|
|
@@ -619,7 +635,8 @@ module Lutaml
|
|
|
619
635
|
attributes: serialize_ag_attributes(ag),
|
|
620
636
|
documentation: extract_documentation(ag),
|
|
621
637
|
source: extract_source_by_type_key_value(
|
|
622
|
-
"attributeGroup", "name", ag.name, prefix, schema_source
|
|
638
|
+
"attributeGroup", "name", ag.name, prefix, schema_source
|
|
639
|
+
),
|
|
623
640
|
instance_xml: generate_instance_xml(ag),
|
|
624
641
|
}
|
|
625
642
|
end.sort_by { |ag| ag[:name] || "" }
|
|
@@ -627,12 +644,13 @@ module Lutaml
|
|
|
627
644
|
|
|
628
645
|
# Extract source information for an attribute group
|
|
629
646
|
# from the schema
|
|
630
|
-
def extract_source_by_type_key_value(type, key, value, prefix = nil,
|
|
647
|
+
def extract_source_by_type_key_value(type, key, value, prefix = nil,
|
|
648
|
+
source = nil)
|
|
631
649
|
return nil unless source && value
|
|
632
650
|
|
|
633
651
|
# parse the schema source and find the attribute group by name
|
|
634
652
|
begin
|
|
635
|
-
doc =
|
|
653
|
+
doc = Moxml::Context.new.parse(source)
|
|
636
654
|
xpath = if prefix
|
|
637
655
|
"//#{prefix}:#{type}[@#{key}='#{value}']"
|
|
638
656
|
else
|
|
@@ -941,8 +959,8 @@ module Lutaml
|
|
|
941
959
|
element_name = elem[:name] || elem[:ref]
|
|
942
960
|
if element_name
|
|
943
961
|
used_by[element_name] << { name: type[:name],
|
|
944
|
-
|
|
945
|
-
|
|
962
|
+
kind: "complexType",
|
|
963
|
+
schema: schema_label }
|
|
946
964
|
end
|
|
947
965
|
if elem[:type]
|
|
948
966
|
type_name = elem[:type].split(":").last || elem[:type]
|
|
@@ -988,7 +1006,7 @@ module Lutaml
|
|
|
988
1006
|
if elem[:type]
|
|
989
1007
|
type_name = elem[:type].split(":").last || elem[:type]
|
|
990
1008
|
used_by[type_name] << { name: elem[:name], kind: "element",
|
|
991
|
-
|
|
1009
|
+
schema: schema_label }
|
|
992
1010
|
end
|
|
993
1011
|
end
|
|
994
1012
|
end
|
|
@@ -11,7 +11,10 @@ module Lutaml
|
|
|
11
11
|
# @param attr [Attribute] Attribute object
|
|
12
12
|
# @return [String, nil] Formatted enumeration default string
|
|
13
13
|
def extract_enumeration_default(attr)
|
|
14
|
-
|
|
14
|
+
unless attr.respond_to?(:simple_type) && attr.simple_type
|
|
15
|
+
return [nil,
|
|
16
|
+
nil]
|
|
17
|
+
end
|
|
15
18
|
|
|
16
19
|
st = attr.simple_type
|
|
17
20
|
if st.respond_to?(:restriction) && st.restriction
|
|
@@ -39,7 +39,7 @@ module Lutaml
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
41
|
# Generate element instance with attributes and content
|
|
42
|
-
def generate_element_instance(element, indent: 1)
|
|
42
|
+
def generate_element_instance(element, indent: 1)
|
|
43
43
|
element_type = find_type(element.type)
|
|
44
44
|
generate_type_instance(
|
|
45
45
|
element_type, tag_name: element.name, indent: indent
|
|
@@ -29,11 +29,11 @@ module Lutaml
|
|
|
29
29
|
# Initialize a new XmlNavigator
|
|
30
30
|
#
|
|
31
31
|
# @param xml_content [String] The XML content to parse
|
|
32
|
-
# @param adapter [Symbol] The Moxml adapter to use (
|
|
32
|
+
# @param adapter [Symbol] The Moxml adapter to use (defaults to Moxml default)
|
|
33
33
|
#
|
|
34
34
|
# @raise [ArgumentError] if xml_content is nil or empty
|
|
35
35
|
# @raise [Moxml::ParseError] if XML parsing fails
|
|
36
|
-
def initialize(xml_content, adapter:
|
|
36
|
+
def initialize(xml_content, adapter: nil)
|
|
37
37
|
raise ArgumentError, "XML content cannot be nil" if xml_content.nil?
|
|
38
38
|
|
|
39
39
|
if xml_content.empty?
|
|
@@ -173,7 +173,7 @@ module Lutaml
|
|
|
173
173
|
# @return [Moxml::Document]
|
|
174
174
|
# @raise [Moxml::ParseError] if parsing fails
|
|
175
175
|
def parse_xml(content, adapter)
|
|
176
|
-
context = Moxml::Context.new(adapter)
|
|
176
|
+
context = adapter ? Moxml::Context.new(adapter) : Moxml::Context.new
|
|
177
177
|
builder = Moxml::DocumentBuilder.new(context)
|
|
178
178
|
builder.build(content)
|
|
179
179
|
rescue StandardError => e
|
data/lib/lutaml/xsd/version.rb
CHANGED
data/lib/lutaml/xsd.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lutaml-xsd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|