xsd 2.0.0 → 2.1.0
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/CHANGELOG.md +5 -0
- data/README.md +11 -2
- data/lib/xsd/base_object.rb +13 -10
- data/lib/xsd/objects/extension.rb +20 -1
- data/lib/xsd/objects/import.rb +7 -7
- data/lib/xsd/objects/include.rb +29 -0
- data/lib/xsd/objects/restriction.rb +20 -0
- data/lib/xsd/objects/schema.rb +13 -7
- data/lib/xsd/version.rb +1 -1
- data/lib/xsd/xml.rb +15 -10
- data/lib/xsd.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3b12830c536c37e72b109727f470d45de29b6c852e62476cd3aa5578dd3b9c7
|
4
|
+
data.tar.gz: 248b65a3794a6c83a6aca695b0d565d55b971991272fd5f7f0a8a841fb8847ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac15d2c2c163bd70f007fd76b5c007fbc786ed09d5609a2d6dba5aa8836144917a5159a32c1b7f47aa250bd18034d8339f445180fc4cd330745138ec60283e32
|
7
|
+
data.tar.gz: 7db0b9ac2ba0c97aab16d84db5145b4a8a18c901f3c24c8fd13a73b96a1998083a41cff38c3b0f7098dc53457b693e0ee5d3d941ceb1712f38a54924d32ce544
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [2.1.0] - 2023-07-10
|
4
|
+
|
5
|
+
- Add support for <xs:include> element
|
6
|
+
- Changed method "schema_for_namespace(namespace) -> XSD::Schema" signature to "schemas_for_namespace(namespace) -> Array<XSD::Schema>"
|
7
|
+
|
3
8
|
## [2.0.0] - 2023-07-07
|
4
9
|
|
5
10
|
- Change XSD::XML.new(file, **options) -> XSD::XML.open(file, **options)
|
data/README.md
CHANGED
@@ -28,20 +28,29 @@ require 'xsd'
|
|
28
28
|
# Load ruby-xsd
|
29
29
|
reader = XSD::XML.open('some.xsd')
|
30
30
|
|
31
|
+
# Get elements and their child elements
|
32
|
+
element = reader['NewReleaseMessage']
|
33
|
+
element.collect_elements.map(&:name) # => ['MessageHeader', 'UpdateIndicator', 'IsBackfill', 'CatalogTransfer', 'WorkList', 'CueSheetList', 'ResourceList', 'CollectionList', 'ReleaseList', 'DealList']
|
34
|
+
|
31
35
|
# Get attributes
|
32
36
|
attribute = reader['NewReleaseMessage']['@MessageSchemaVersionId']
|
33
37
|
|
34
|
-
# Get
|
38
|
+
# Get attribute information
|
35
39
|
attribute.name # => 'MessageSchemaVersionId'
|
36
40
|
attribute.type # => 'xs:string'
|
37
41
|
attribute.required? # => true
|
42
|
+
attribute.optional? # => false
|
43
|
+
attribute.prohibited? # => true
|
38
44
|
|
39
45
|
# Get element information
|
40
|
-
element = reader['NewReleaseMessage']['ResourceList']['SoundRecording']
|
46
|
+
element = reader['NewReleaseMessage']['ResourceList']['SoundRecording'] # => XSD::Element
|
41
47
|
element.min_occurs # => 0
|
42
48
|
element.max_occurs # => :unbounded
|
43
49
|
element.type # => 'ern:SoundRecording'
|
44
50
|
element.complex_type # => XSD::ComplexType
|
51
|
+
element.complex? # => true
|
52
|
+
element.multiple_allowed? # => true
|
53
|
+
element.required? # => false
|
45
54
|
```
|
46
55
|
|
47
56
|
## Development
|
data/lib/xsd/base_object.rb
CHANGED
@@ -67,13 +67,13 @@ module XSD
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# Get schema by namespace or namespace prefix
|
70
|
-
# @param [String] namespace
|
71
|
-
# @return Schema
|
72
|
-
def
|
70
|
+
# @param [String, nil] namespace
|
71
|
+
# @return Array<Schema>
|
72
|
+
def schemas_for_namespace(namespace)
|
73
73
|
if schema.targets_namespace?(namespace)
|
74
|
-
schema
|
74
|
+
[schema, *schema.includes.map(&:imported_schema)]
|
75
75
|
elsif (import = schema.import_by_namespace(namespace))
|
76
|
-
import.imported_schema
|
76
|
+
[import.imported_schema]
|
77
77
|
else
|
78
78
|
raise Error, "Schema not found for namespace '#{namespace}' in '#{schema.id || schema.target_namespace}'"
|
79
79
|
end
|
@@ -112,12 +112,15 @@ module XSD
|
|
112
112
|
return nil if schema.namespace_prefix == name_prefix
|
113
113
|
|
114
114
|
# determine schema for namespace
|
115
|
-
|
115
|
+
search_schemas = schemas_for_namespace(name_prefix)
|
116
116
|
|
117
117
|
# find element in target schema
|
118
|
-
|
118
|
+
search_schemas.each do |s|
|
119
|
+
node = s.node.xpath("./xs:#{node_name}[@name=\"#{name_local}\"]", { 'xs' => XML_SCHEMA }).first
|
120
|
+
return s.node_to_object(node) if node
|
121
|
+
end
|
119
122
|
|
120
|
-
|
123
|
+
nil
|
121
124
|
end
|
122
125
|
|
123
126
|
# Get reader object for node
|
@@ -169,9 +172,9 @@ module XSD
|
|
169
172
|
|
170
173
|
# Get namespace prefix from node name
|
171
174
|
# @param [String, nil] name Name to strip from
|
172
|
-
# @return String
|
175
|
+
# @return String, nil
|
173
176
|
def get_prefix(name)
|
174
|
-
name&.include?(':') ? name.split(':').first :
|
177
|
+
name&.include?(':') ? name.split(':').first : nil
|
175
178
|
end
|
176
179
|
|
177
180
|
# Return element documentation
|
@@ -8,7 +8,26 @@ module XSD
|
|
8
8
|
TYPE_PROPERTY = nil
|
9
9
|
|
10
10
|
include Based
|
11
|
-
include SimpleTyped
|
12
11
|
include AttributeContainer
|
12
|
+
|
13
|
+
# Nested group
|
14
|
+
# @!attribute group
|
15
|
+
# @return Group
|
16
|
+
child :group, :group
|
17
|
+
|
18
|
+
# Nested all
|
19
|
+
# @!attribute all
|
20
|
+
# @return All
|
21
|
+
child :all, :all
|
22
|
+
|
23
|
+
# Nested choice
|
24
|
+
# @!attribute choice
|
25
|
+
# @return Choice
|
26
|
+
child :choice, :choice
|
27
|
+
|
28
|
+
# Nested sequence
|
29
|
+
# @!attribute sequence
|
30
|
+
# @return Sequence
|
31
|
+
child :sequence, :sequence
|
13
32
|
end
|
14
33
|
end
|
data/lib/xsd/objects/import.rb
CHANGED
@@ -16,23 +16,23 @@ module XSD
|
|
16
16
|
property :schemaLocation, :string
|
17
17
|
|
18
18
|
# Get imported schema
|
19
|
-
# @return
|
19
|
+
# @return Schema
|
20
20
|
def imported_schema
|
21
|
-
|
22
|
-
return
|
21
|
+
known_schemas = reader.schemas_for_namespace(namespace)
|
22
|
+
return known_schemas.first if known_schemas.any?
|
23
23
|
|
24
24
|
unless schema_location
|
25
25
|
raise ImportError, "Schema location not provided for namespace '#{namespace}', use add_schema_xml()/add_schema_node()"
|
26
26
|
end
|
27
27
|
|
28
28
|
xml = reader.resource_resolver.call(schema_location, namespace)
|
29
|
-
|
29
|
+
new_schema = reader.add_schema_xml(xml)
|
30
30
|
|
31
|
-
unless namespace ==
|
32
|
-
raise ImportError, 'Import
|
31
|
+
unless namespace == new_schema.target_namespace
|
32
|
+
raise ImportError, 'Import namespace does not match imported schema targetNamespace'
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
new_schema
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module XSD
|
4
|
+
# The include element is used to add multiple schemas with the same target namespace to a document.
|
5
|
+
# Parent elements: schema
|
6
|
+
# https://www.w3schools.com/xml/el_include.asp
|
7
|
+
class Include < BaseObject
|
8
|
+
# Required. Specifies the URI to the schema to include in the target namespace of the containing schema
|
9
|
+
# @!attribute schema_location
|
10
|
+
# @return String
|
11
|
+
property :schemaLocation, :string
|
12
|
+
|
13
|
+
# Get imported schema
|
14
|
+
# @return Schema
|
15
|
+
def imported_schema
|
16
|
+
# cache included schema locally as it has no unique namespace to check in global registry
|
17
|
+
return @imported_schema if @imported_schema
|
18
|
+
|
19
|
+
xml = reader.resource_resolver.call(schema_location)
|
20
|
+
new_schema = reader.add_schema_xml(xml)
|
21
|
+
|
22
|
+
unless schema.target_namespace == new_schema.target_namespace
|
23
|
+
raise ImportError, 'Schema targetNamespace does not match included schema targetNamespace'
|
24
|
+
end
|
25
|
+
|
26
|
+
@imported_schema = new_schema
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -16,6 +16,26 @@ module XSD
|
|
16
16
|
fractionDigits length minLength maxLength enumeration whiteSpace pattern
|
17
17
|
].freeze
|
18
18
|
|
19
|
+
# Nested group
|
20
|
+
# @!attribute group
|
21
|
+
# @return Group
|
22
|
+
child :group, :group
|
23
|
+
|
24
|
+
# Nested all
|
25
|
+
# @!attribute all
|
26
|
+
# @return All
|
27
|
+
child :all, :all
|
28
|
+
|
29
|
+
# Nested choice
|
30
|
+
# @!attribute choice
|
31
|
+
# @return Choice
|
32
|
+
child :choice, :choice
|
33
|
+
|
34
|
+
# Nested sequence
|
35
|
+
# @!attribute sequence
|
36
|
+
# @return Sequence
|
37
|
+
child :sequence, :sequence
|
38
|
+
|
19
39
|
# Get restriction facets
|
20
40
|
# @return Hash
|
21
41
|
def facets
|
data/lib/xsd/objects/schema.rb
CHANGED
@@ -85,6 +85,11 @@ module XSD
|
|
85
85
|
# @return Array<Import>
|
86
86
|
child :imports, [:import]
|
87
87
|
|
88
|
+
# Schema includes
|
89
|
+
# @!attribute includes
|
90
|
+
# @return Array<Include>
|
91
|
+
child :includes, [:include]
|
92
|
+
|
88
93
|
# Get current schema object
|
89
94
|
# @return Schema
|
90
95
|
def schema
|
@@ -116,30 +121,31 @@ module XSD
|
|
116
121
|
end
|
117
122
|
|
118
123
|
# Check if namespace is a target namespace
|
119
|
-
# @param [String] namespace
|
124
|
+
# @param [String, nil] namespace
|
120
125
|
# @return Boolean
|
121
126
|
def targets_namespace?(namespace)
|
122
127
|
namespace == target_namespace || namespaces[namespace.empty? ? 'xmlns' : "xmlns:#{namespace}"] == target_namespace
|
123
128
|
end
|
124
129
|
|
125
|
-
# Override map_children on schema to get objects from all
|
130
|
+
# Override map_children on schema to get objects from all loaded schemas
|
126
131
|
# @param [Symbol] name
|
127
132
|
# @return Array<BaseObject>
|
128
133
|
def map_children(name, cache = {})
|
129
134
|
super(name) + import_map_children(name, cache)
|
130
135
|
end
|
131
136
|
|
132
|
-
# Get children from all
|
137
|
+
# Get children from all loaded schemas
|
133
138
|
# @param [Symbol] name
|
134
139
|
# @return Array<BaseObject>
|
135
140
|
def import_map_children(name, cache)
|
136
|
-
return [] if name.to_sym
|
141
|
+
return [] if %i[import include].include?(name.to_sym)
|
137
142
|
|
138
|
-
imports.map do |import|
|
139
|
-
|
143
|
+
(includes + imports).map do |import|
|
144
|
+
key = import.respond_to?(:namespace) && import.namespace ? import.namespace : import.schema_location
|
145
|
+
if cache.key?(key)
|
140
146
|
nil
|
141
147
|
else
|
142
|
-
cache[
|
148
|
+
cache[key] = true
|
143
149
|
import.imported_schema.map_children(name, cache)
|
144
150
|
end
|
145
151
|
end.compact.flatten
|
data/lib/xsd/version.rb
CHANGED
data/lib/xsd/xml.rb
CHANGED
@@ -31,6 +31,7 @@ module XSD
|
|
31
31
|
'complexContent' => ComplexContent,
|
32
32
|
'extension' => Extension,
|
33
33
|
'import' => Import,
|
34
|
+
'include' => Include,
|
34
35
|
'simpleType' => SimpleType,
|
35
36
|
'all' => All,
|
36
37
|
'restriction' => Restriction,
|
@@ -63,6 +64,10 @@ module XSD
|
|
63
64
|
'pattern' => Facet
|
64
65
|
}.freeze
|
65
66
|
|
67
|
+
# Create reader from a file path
|
68
|
+
# @param [String] path
|
69
|
+
# @param [Hash] options
|
70
|
+
# @return XML
|
66
71
|
def self.open(path, **options)
|
67
72
|
reader = new(**options)
|
68
73
|
reader.add_schema_xml(File.read(path))
|
@@ -92,8 +97,8 @@ module XSD
|
|
92
97
|
Nokogiri::XML(xml)
|
93
98
|
end
|
94
99
|
|
95
|
-
#
|
96
|
-
# @return
|
100
|
+
# Add schema xml to reader instance
|
101
|
+
# @return Schema
|
97
102
|
def add_schema_xml(xml)
|
98
103
|
doc = read_document(xml)
|
99
104
|
raise Error, 'Schema node not found, xml does not seem to be a valid XSD' unless doc.root&.name == 'schema'
|
@@ -101,15 +106,14 @@ module XSD
|
|
101
106
|
add_schema_node(doc.root)
|
102
107
|
end
|
103
108
|
|
104
|
-
#
|
109
|
+
# Add schema node to reader instance
|
105
110
|
# @return Schema
|
106
111
|
def add_schema_node(node)
|
107
112
|
raise Error, 'Added schema must be of type Nokogiri::XML::Node' unless node.is_a?(Nokogiri::XML::Node)
|
108
113
|
|
109
|
-
|
110
|
-
schemas.push(
|
111
|
-
|
112
|
-
schema
|
114
|
+
new_schema = Schema.new(options.merge(node: node, reader: self))
|
115
|
+
schemas.push(new_schema)
|
116
|
+
new_schema
|
113
117
|
end
|
114
118
|
|
115
119
|
# Add prefixes defined outside of processed schemas, for example in WSDL document
|
@@ -126,10 +130,11 @@ module XSD
|
|
126
130
|
end
|
127
131
|
|
128
132
|
# Get schema by namespace or namespace prefix
|
129
|
-
# @
|
130
|
-
|
133
|
+
# @param [String, nil] namespace
|
134
|
+
# @return Array<Schema>
|
135
|
+
def schemas_for_namespace(namespace)
|
131
136
|
namespace = namespace_prefixes[namespace] if namespace_prefixes.key?(namespace)
|
132
|
-
schemas.
|
137
|
+
schemas.select { |schema| schema.target_namespace == namespace }
|
133
138
|
end
|
134
139
|
|
135
140
|
def [](*args)
|
data/lib/xsd.rb
CHANGED
@@ -18,6 +18,7 @@ require 'xsd/objects/simple_content'
|
|
18
18
|
require 'xsd/objects/complex_content'
|
19
19
|
require 'xsd/objects/extension'
|
20
20
|
require 'xsd/objects/import'
|
21
|
+
require 'xsd/objects/include'
|
21
22
|
require 'xsd/objects/restriction'
|
22
23
|
require 'xsd/objects/group'
|
23
24
|
require 'xsd/objects/all'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xsd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- d.arkhipov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/xsd/objects/field.rb
|
91
91
|
- lib/xsd/objects/group.rb
|
92
92
|
- lib/xsd/objects/import.rb
|
93
|
+
- lib/xsd/objects/include.rb
|
93
94
|
- lib/xsd/objects/key.rb
|
94
95
|
- lib/xsd/objects/keyref.rb
|
95
96
|
- lib/xsd/objects/list.rb
|