xsd 1.0.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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +124 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +21 -0
  8. data/Makefile +7 -0
  9. data/README.md +68 -0
  10. data/Rakefile +25 -0
  11. data/lib/xsd/base_object.rb +347 -0
  12. data/lib/xsd/exceptions.rb +12 -0
  13. data/lib/xsd/generator.rb +137 -0
  14. data/lib/xsd/objects/all.rb +22 -0
  15. data/lib/xsd/objects/annotation.rb +19 -0
  16. data/lib/xsd/objects/any.rb +31 -0
  17. data/lib/xsd/objects/any_attribute.rb +30 -0
  18. data/lib/xsd/objects/appinfo.rb +13 -0
  19. data/lib/xsd/objects/attribute.rb +72 -0
  20. data/lib/xsd/objects/attribute_group.rb +18 -0
  21. data/lib/xsd/objects/choice.rb +33 -0
  22. data/lib/xsd/objects/complex_content.rb +25 -0
  23. data/lib/xsd/objects/complex_type.rb +82 -0
  24. data/lib/xsd/objects/documentation.rb +18 -0
  25. data/lib/xsd/objects/element.rb +130 -0
  26. data/lib/xsd/objects/extension.rb +14 -0
  27. data/lib/xsd/objects/facet.rb +12 -0
  28. data/lib/xsd/objects/field.rb +13 -0
  29. data/lib/xsd/objects/group.rb +32 -0
  30. data/lib/xsd/objects/import.rb +67 -0
  31. data/lib/xsd/objects/key.rb +25 -0
  32. data/lib/xsd/objects/keyref.rb +33 -0
  33. data/lib/xsd/objects/list.rb +18 -0
  34. data/lib/xsd/objects/restriction.rb +49 -0
  35. data/lib/xsd/objects/schema.rb +155 -0
  36. data/lib/xsd/objects/selector.rb +15 -0
  37. data/lib/xsd/objects/sequence.rb +33 -0
  38. data/lib/xsd/objects/simple_content.rb +19 -0
  39. data/lib/xsd/objects/simple_type.rb +35 -0
  40. data/lib/xsd/objects/union.rb +23 -0
  41. data/lib/xsd/objects/unique.rb +18 -0
  42. data/lib/xsd/shared/attribute_container.rb +17 -0
  43. data/lib/xsd/shared/based.rb +37 -0
  44. data/lib/xsd/shared/complex_typed.rb +28 -0
  45. data/lib/xsd/shared/element_container.rb +12 -0
  46. data/lib/xsd/shared/min_max_occurs.rb +46 -0
  47. data/lib/xsd/shared/referenced.rb +24 -0
  48. data/lib/xsd/shared/simple_typed.rb +14 -0
  49. data/lib/xsd/validator.rb +90 -0
  50. data/lib/xsd/version.rb +5 -0
  51. data/lib/xsd/xml.rb +111 -0
  52. data/lib/xsd.rb +42 -0
  53. data/xsd.gemspec +45 -0
  54. metadata +239 -0
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The attributeGroup element is used to group a set of attribute declarations so that they can be incorporated as a
5
+ # group into complex type definitions.
6
+ # Parent elements: attributeGroup, complexType, schema, restriction (both simpleContent and complexContent),
7
+ # extension (both simpleContent and complexContent
8
+ # https://www.w3schools.com/xml/el_attributegroup.asp
9
+ class AttributeGroup < BaseObject
10
+ include Referenced
11
+ include AttributeContainer
12
+
13
+ # Optional. Specifies the name of the attribute. Name and ref attributes cannot both be present
14
+ # @!attribute name
15
+ # @return [String]
16
+ property :name, :string
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # XML Schema choice element allows only one of the elements contained in the <choice> declaration to be present
5
+ # within the containing element.
6
+ # Parent elements: group, choice, sequence, complexType, restriction (both simpleContent and complexContent),
7
+ # extension (both simpleContent and complexContent)
8
+ # https://www.w3schools.com/xml/el_choice.asp
9
+ class Choice < BaseObject
10
+ include MinMaxOccurs
11
+ include ElementContainer
12
+
13
+ # Nested groups
14
+ # @!attribute groups
15
+ # @return [Array<Group>]
16
+ child :groups, [:group]
17
+
18
+ # Nested choices
19
+ # @!attribute choices
20
+ # @return [Array<Choice>]
21
+ child :choices, [:choice]
22
+
23
+ # Nested sequences
24
+ # @!attribute sequences
25
+ # @return [Array<Sequence>]
26
+ child :sequences, [:sequence]
27
+
28
+ # Nested anys
29
+ # @!attribute anys
30
+ # @return [Array<Any>]
31
+ child :anys, [:any]
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The complexContent element defines extensions or restrictions
5
+ # on a complex type that contains mixed content or elements only.
6
+ # Parent elements: complexType
7
+ # https://www.w3schools.com/xml/el_complexcontent.asp
8
+ class ComplexContent < BaseObject
9
+ # Optional. Specifies whether character data is allowed to appear between the child elements of this complexType
10
+ # element. Default is false
11
+ # @!attribute mixed
12
+ # @return [Boolean]
13
+ property :mixed, :boolean, default: false
14
+
15
+ # Get nested extension
16
+ # @!attribute extension
17
+ # @return [Extension, nil]
18
+ child :extension, :extension
19
+
20
+ # Get nested restriction
21
+ # @!attribute restriction
22
+ # @return [Restriction, nil]
23
+ child :restriction, :restriction
24
+ end
25
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The complexType element defines a complex type. A complex type element is an XML element that contains other
5
+ # elements and/or attributes.
6
+ # Parent elements: element, redefine, schema
7
+ # https://www.w3schools.com/xml/el_complextype.asp
8
+ class ComplexType < BaseObject
9
+ include AttributeContainer
10
+
11
+ # Optional. Specifies the name of the attribute. Name and ref attributes cannot both be present
12
+ # @!attribute name
13
+ # @return [String]
14
+ property :name, :string
15
+
16
+ # Optional. Specifies whether the complex type can be used in an instance document. True indicates that an element
17
+ # cannot use this complex type directly but must use a complex type derived from this complex type. Default is false
18
+ # @!attribute abstract
19
+ # @return [Boolean]
20
+ property :abstract, :boolean, default: false
21
+
22
+ # Optional. Specifies whether character data is allowed to appear between the child elements of this complexType
23
+ # element. Default is false. If a simpleContent element is a child element, the mixed attribute is not allowed!
24
+ # @!attribute mixed
25
+ # @return [Boolean]
26
+ property :mixed, :boolean, default: false
27
+
28
+ # Optional. Prevents a complex type that has a specified type of derivation from being used in place of this
29
+ # complex type. This value can contain #all or a list that is a subset of extension or restriction:
30
+ # extension - prevents complex types derived by extension
31
+ # restriction - prevents complex types derived by restriction
32
+ # #all - prevents all derived complex types
33
+ # @!attribute block
34
+ # @return [String, nil]
35
+ property :block, :string
36
+
37
+ # Optional. Prevents a specified type of derivation of this complex type element. Can contain #all or a list
38
+ # that is a subset of extension or restriction.
39
+ # extension - prevents derivation by extension
40
+ # restriction - prevents derivation by restriction
41
+ # #all - prevents all derivation
42
+ # @!attribute final
43
+ # @return [String, nil]
44
+ property :final, :string
45
+
46
+ # Simple content object
47
+ # @!attribute simple_content
48
+ # @return [SimpleContent]
49
+ child :simple_content, :simpleContent
50
+
51
+ # Complex content object
52
+ # @!attribute complex_content
53
+ # @return [ComplexContent]
54
+ child :complex_content, :complexContent
55
+
56
+ # Nested group
57
+ # @!attribute group
58
+ # @return [Group]
59
+ child :group, :group
60
+
61
+ # Nested all
62
+ # @!attribute all
63
+ # @return [All]
64
+ child :all, :all
65
+
66
+ # Nested choice
67
+ # @!attribute choice
68
+ # @return [Choice]
69
+ child :choice, :choice
70
+
71
+ # Nested sequence
72
+ # @!attribute sequence
73
+ # @return [Sequence]
74
+ child :sequence, :sequence
75
+
76
+ # Determine if this is a linked type
77
+ # @return [Boolean]
78
+ def linked?
79
+ !name.nil?
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The documentation element is used to enter text comments in a schema.
5
+ # Parent elements: annotation
6
+ # https://www.w3schools.com/xml/el_documentation.asp
7
+ class Documentation < BaseObject
8
+ # Optional. A URI reference that specifies the source of the application information
9
+ # @!attribute source
10
+ # @return [String]
11
+ property :source, :string
12
+
13
+ # Optional. Specifies the language used in the contents
14
+ # @!attribute xml_lang
15
+ # @return [String]
16
+ property :'xml:lang', :string
17
+ end
18
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The element element defines an element.
5
+ # Parent elements: schema, choice, all, sequence, group
6
+ # https://www.w3schools.com/xml/el_element.asp
7
+ class Element < BaseObject
8
+ TYPE_PROPERTY = :type
9
+
10
+ include MinMaxOccurs
11
+ include SimpleTyped
12
+ include ComplexTyped
13
+ include Referenced
14
+
15
+ # Optional. Specifies the name of the attribute. Name and ref attributes cannot both be present
16
+ # @!attribute name
17
+ # @return [String]
18
+ property :name, :string
19
+
20
+ # Optional. Specifies either the name of a built-in data type, or the name of a simpleType or complexType element
21
+ # @!attribute type
22
+ # @return [String, nil]
23
+ property :type, :string
24
+
25
+ # Optional. Specifies the name of an element that can be substituted with this element. This attribute cannot be
26
+ # used if the parent element is not the schema element
27
+ # @!attribute substitution_group
28
+ # @return [String, nil]
29
+ property :substitutionGroup, :string
30
+
31
+ # Optional. Specifies a default value for the element (can only be used if the element's content is a simple type
32
+ # or text only)
33
+ # @!attribute default
34
+ # @return [String, nil]
35
+ property :default, :string
36
+
37
+ # Optional. Specifies a fixed value for the element (can only be used if the element's content is a simple type
38
+ # or text only)
39
+ # @!attribute fixed
40
+ # @return [String, nil]
41
+ property :fixed, :string
42
+
43
+ # Optional. Specifies the form for the element. "unqualified" indicates that this element is not required to be
44
+ # qualified with the namespace prefix. "qualified" indicates that this element must be qualified with the namespace
45
+ # prefix. The default value is the value of the elementFormDefault attribute of the schema element. This attribute
46
+ # cannot be used if the parent element is the schema element
47
+ # @!attribute form
48
+ # @return [String]
49
+ property :form, :string
50
+
51
+ # Optional. Specifies whether an explicit null value can be assigned to the element. True enables an instance of
52
+ # the element to have the null attribute set to true. The null attribute is defined as part of the XML Schema
53
+ # namespace for instances. Default is false
54
+ # @!attribute nillable
55
+ # @return [Boolean]
56
+ property :nillable, :boolean, default: false
57
+
58
+ # Optional. Specifies whether the element can be used in an instance document. True indicates that the element
59
+ # cannot appear in the instance document. Instead, another element whose substitutionGroup attribute contains the
60
+ # qualified name (QName) of this element must appear in this element's place. Default is false
61
+ # @!attribute abstract
62
+ # @return [Boolean]
63
+ property :abstract, :boolean, default: false
64
+
65
+ # Optional. Prevents an element with a specified type of derivation from being used in place of this element.
66
+ # This value can contain #all or a list that is a subset of extension, restriction, or equivClass:
67
+ # extension - prevents elements derived by extension
68
+ # restriction - prevents elements derived by restriction
69
+ # substitution - prevents elements derived by substitution
70
+ # #all - prevents all derived elements
71
+ # @!attribute block
72
+ # @return [String, nil]
73
+ property :block, :string
74
+
75
+ # Optional. Sets the default value of the final attribute on the element element. This attribute cannot be used if
76
+ # the parent element is not the schema element. This value can contain #all or a list that is a subset of extension
77
+ # or restriction:
78
+ # extension - prevents elements derived by extension
79
+ # restriction - prevents elements derived by restriction
80
+ # #all - prevents all derived elements
81
+ # @!attribute final
82
+ # @return [String, nil]
83
+ property :final, :string
84
+
85
+ # Nested unique objects
86
+ # @!attribute unique
87
+ # @return [Array<Unique>]
88
+ child :unique, [:unique]
89
+
90
+ # Determine if element is required
91
+ # @return [Boolean]
92
+ def required?
93
+ computed_min_occurs > 0
94
+ end
95
+
96
+ # Determine if element is optional
97
+ # @return [Boolean]
98
+ def optional?
99
+ !required?
100
+ end
101
+
102
+ # Determine if element may occur multiple times
103
+ # @return [Boolean]
104
+ def multiple_allowed?
105
+ computed_max_occurs == :unbounded || computed_max_occurs > 1
106
+ end
107
+
108
+ # Determine if element has complex content
109
+ # @return [Boolean]
110
+ def complex?
111
+ complex_type && !complex_type.simple_content && all_elements.any?
112
+ end
113
+
114
+ # Get elements that can appear instead of this one
115
+ # @return [Array<Element>]
116
+ def substitution_elements
117
+ # TODO: for now we do not search in parent schemas (that imported current schema)
118
+ # TODO: refactor for better namespace handling (use xpath with namespaces or correct comparison)
119
+ schema.all_elements.select do |element|
120
+ element.substitution_group&.split(':')&.last == name
121
+ end
122
+ end
123
+
124
+ # Get target namespace
125
+ # @return [String]
126
+ def target_namespace
127
+ schema.target_namespace
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The extension element extends an existing simpleType or complexType element.
5
+ # Parent elements: simpleContent, complexContent
6
+ # https://www.w3schools.com/xml/el_extension.asp
7
+ class Extension < BaseObject
8
+ TYPE_PROPERTY = nil
9
+
10
+ include Based
11
+ include SimpleTyped
12
+ include AttributeContainer
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # Virtual object for all restriction facets
5
+ # Parent elements: restriction
6
+ class Facet < BaseObject
7
+ # Returns facet value
8
+ # @!attribute value
9
+ # @return [String]
10
+ property :value, :string
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The field element specifies an XPath expression that specifies the value used to define an identity constraint.
5
+ # Parent elements: key, keyref, unique
6
+ # https://www.w3schools.com/xml/el_field.asp
7
+ class Field < BaseObject
8
+ # Required. Identifies a single element or attribute whose content or value is used for the constraint
9
+ # @!attribute xpath
10
+ # @return [String]
11
+ property :xpath, :string, required: true
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The group element is used to define a group of elements to be used in complex type definitions.
5
+ # Parent elements: schema, choice, sequence, complexType, restriction (both simpleContent and complexContent),
6
+ # extension (both simpleContent and complexContent)
7
+ # https://www.w3schools.com/xml/el_group.asp
8
+ class Group < BaseObject
9
+ include MinMaxOccurs
10
+ include Referenced
11
+
12
+ # Optional. Specifies the name of the attribute. Name and ref attributes cannot both be present
13
+ # @!attribute name
14
+ # @return [String]
15
+ property :name, :string
16
+
17
+ # Nested all object
18
+ # @!attribute all
19
+ # @return [All]
20
+ child :all, :all
21
+
22
+ # Nested choice object
23
+ # @!attribute choice
24
+ # @return [Choice]
25
+ child :choice, :choice
26
+
27
+ # Nested sequence object
28
+ # @!attribute sequence
29
+ # @return [Sequence]
30
+ child :sequence, :sequence
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+
5
+ module XSD
6
+ # The import element is used to add multiple schemas with different target namespace to a document.
7
+ # Parent elements: schema
8
+ # https://www.w3schools.com/xml/el_import.asp
9
+ class Import < BaseObject
10
+ # Optional. Specifies the URI of the namespace to import
11
+ # @!attribute namespace
12
+ # @return [String, nil]
13
+ property :namespace, :string
14
+
15
+ # Optional. Specifies the URI to the schema for the imported namespace
16
+ # @!attribute schema_location
17
+ # @return [String, nil]
18
+ property :schemaLocation, :string
19
+
20
+ # Get imported reader
21
+ # @return [XSD:XML]
22
+ def imported_reader
23
+ return @imported_reader if @imported_reader
24
+
25
+ xml = if reader.imported_xsd[namespace]
26
+ # check in imported xsd by namespace
27
+ reader.imported_xsd[namespace]
28
+ elsif schema_location =~ /^https?:/
29
+ # check http(s) schema location
30
+ download_uri(schema_location)
31
+ elsif (path = local_path)
32
+ # check local relative path
33
+ path
34
+ elsif namespace =~ /^https?:/
35
+ # check http(s) namespace
36
+ # TODO: investigate spec conformance
37
+ download_uri(namespace.gsub(/#{File.basename(schema_location, '.*')}$/, '').to_s + schema_location)
38
+ else
39
+ raise ImportError, "Failed to locate import '#{schema_location}' for namespace '#{namespace}'"
40
+ end
41
+
42
+ # TODO: pass all provided options
43
+ @imported_reader = XSD::XML.new(xml, imported_xsd: reader.imported_xsd, logger: reader.logger)
44
+ end
45
+
46
+ def local_path
47
+ return unless reader.xsd.is_a?(Pathname)
48
+
49
+ path = reader.xsd.dirname.join(schema_location)
50
+ path.file? ? path : nil
51
+ end
52
+
53
+ private
54
+
55
+ def download_uri(uri)
56
+ reader.logger.debug(XSD) { "Downloading import schema for namespace '#{namespace}' from '#{uri}'" }
57
+
58
+ begin
59
+ response = RestClient.get(uri)
60
+ rescue RestClient::Exception => e
61
+ raise ImportError, e.message
62
+ end
63
+
64
+ response.body
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The unique element defines that an element or an attribute value must be unique within the scope.
5
+ # Parent elements: element
6
+ # https://www.w3schools.com/xml/el_unique.asp
7
+ class Key < BaseObject
8
+ # The name of the key element.
9
+ # The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification.
10
+ # The name must be unique within an identity constraint set. Required.
11
+ # @!attribute name
12
+ # @return [String]
13
+ property :name, :string, required: true
14
+
15
+ # Get nested selector object
16
+ # @!attribute selector
17
+ # @return [Selector]
18
+ child :selector, :selector
19
+
20
+ # Get nested field objects
21
+ # @!attribute fields
22
+ # @return [Array<Field>]
23
+ child :fields, [:field]
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The unique element defines that an element or an attribute value must be unique within the scope.
5
+ # Parent elements: element
6
+ # https://www.w3schools.com/xml/el_unique.asp
7
+ class Keyref < BaseObject
8
+ # The name of the keyref element.
9
+ # The name must be a no-colon-name (NCName) as defined in the XML Namespaces specification.
10
+ # The name must be unique within an identity constraint set. Required.
11
+ # @!attribute name
12
+ # @return [String]
13
+ property :name, :string, required: true
14
+
15
+ # The name of a key or unique element defined in this schema
16
+ # (or another schema indicated by the specified namespace).
17
+ # The refer value must be a qualified name (QName).
18
+ # The type can include a namespace prefix. Required.
19
+ # @!attribute refer
20
+ # @return [String]
21
+ property :refer, :string, required: true
22
+
23
+ # Get nested selector object
24
+ # @!attribute selector
25
+ # @return [Selector]
26
+ child :selector, :selector
27
+
28
+ # Get nested field objects
29
+ # @!attribute fields
30
+ # @return [Array<Field>]
31
+ child :fields, [:field]
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The list element defines a simple type element as a list of values of a specified data type.
5
+ # Parent elements: simpleType
6
+ # https://www.w3schools.com/xml/el_list.asp
7
+ class List < BaseObject
8
+ TYPE_PROPERTY = :itemType
9
+
10
+ include SimpleTyped
11
+
12
+ # Specifies the name of a built-in data type or simpleType element defined in this or another schema.
13
+ # This attribute is not allowed if the content contains a simpleType element, otherwise it is required
14
+ # @!attribute item_type
15
+ # @return [String, nil]
16
+ property :itemType, :string
17
+ end
18
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XSD
4
+ # The restriction element defines restrictions on a simpleType, simpleContent, or complexContent definition.
5
+ # Parent elements: simpleType, simpleContent, complexContent
6
+ # https://www.w3schools.com/xml/el_restriction.asp
7
+ class Restriction < BaseObject
8
+ TYPE_PROPERTY = nil
9
+
10
+ include Based
11
+ include SimpleTyped
12
+ include AttributeContainer
13
+
14
+ FACET_ELEMENTS = %w[
15
+ minExclusive minInclusive maxExclusive maxInclusive totalDigits
16
+ fractionDigits length minLength maxLength enumeration whiteSpace pattern
17
+ ].freeze
18
+
19
+ # Get restriction facets
20
+ # @return [Hash]
21
+ def facets
22
+ nodes.inject({}) do |hash, node|
23
+ if FACET_ELEMENTS.include?(node.name)
24
+ key = node.name
25
+ value = node['value']
26
+
27
+ if key == 'enumeration'
28
+ hash[key] ||= {}
29
+ hash[key][value] = documentation_for(node)
30
+ elsif key == 'pattern'
31
+ hash[key] ||= []
32
+ hash[key].push(value)
33
+ else
34
+ hash[key] = value
35
+ end
36
+ end
37
+ hash
38
+ end
39
+ end
40
+
41
+ # Get all available elements on the current stack level, optionally including base type elements
42
+ # @param [Boolean] include_base
43
+ # @return [Array<Element>]
44
+ def all_elements(include_base = false)
45
+ # By default we do not include base element for complex restrictions
46
+ super
47
+ end
48
+ end
49
+ end