validate_xml_xsi 0.3.0 → 0.4.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 +4 -4
- data/lib/validate_xml_xsi.rb +60 -21
- data/validate_xml_xsi.gemspec +1 -1
- metadata +3 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dbe79de11a54ebfff237869fbef6f4ccb9ce8b063dc3305299cb1fcb7856298b
|
|
4
|
+
data.tar.gz: 549031f8aa72adca7434f9294bfef40e2b2ce70b8980b04960cd20ab320dace4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1336127c5245a94b7a8915f5d87372e17ab52bad43c32d1c07ef165d26db0ca1182baefcc826bd58cd401e213a2f7c04129dfea28d7c950d9fe1e06e2bb6780a
|
|
7
|
+
data.tar.gz: b60f8dcc6904c9b706f338a7afa7438fd98b7029a2a06b9f07010a63e3cddd1f0913bad0bc5ec2d608c3446c137339bb2ae8640251e7b4775ac006b9799e0c75
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## v0.3.0
|
|
2
|
+
|
|
3
|
+
* Change overall structure to make XML_XSI::Schema a normal class (not just a singleton)
|
|
4
|
+
* Allow the Schema to return the xsd document string (so it can be used externally to build a XSD document tree)
|
|
5
|
+
|
|
1
6
|
## v0.2.4
|
|
2
7
|
|
|
3
8
|
* Fix some silly syntax errors
|
data/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# validate_xml_xsi
|
|
2
2
|
|
|
3
|
-
This gem validates XML against it's
|
|
3
|
+
This gem validates XML against it's XSD that is created from xsi:schemaLocation elements.
|
|
4
4
|
|
|
5
|
-
It does this by first parsing the XML and searching for xsi:schemaLocation
|
|
5
|
+
It does this by first parsing the XML and searching for elements that include xsi:schemaLocation attributes. It then creates an XSD schema document that includes the root namespace and further imports additional namespaces discovered in the XML.
|
|
6
6
|
|
|
7
|
-
It then validates the document against that schema and outputs any error messages.
|
|
7
|
+
It then validates the document against that constructed schema document and outputs any error messages.
|
|
8
8
|
|
|
9
|
-
Note: this gem utilizes the 'nokogiri' gem for XML parsing and schema validation.
|
|
9
|
+
Note: this gem utilizes the 'nokogiri' gem (which in turn relies on Gnome's libxml2) for the XML parsing and schema validation.
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
data/lib/validate_xml_xsi.rb
CHANGED
|
@@ -35,41 +35,53 @@ class XML_XSI
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
attr_reader :xsd
|
|
38
|
-
def initialize(xml_doc)
|
|
38
|
+
def initialize(xml_doc, parent_xml_doc = nil)
|
|
39
39
|
unless xml_doc.is_a?(Nokogiri::XML::Document)
|
|
40
40
|
raise DocumentError.new("invalid Nokogiri::XML::Document - #{xml_doc.class.name}")
|
|
41
41
|
end
|
|
42
|
+
unless parent_xml_doc.nil? || parent_xml_doc.is_a?(Nokogiri::XML::Document)
|
|
43
|
+
raise DocumentError.new("invalid parent Nokogiri::XML::Document - #{parent_xml_doc.class.name}")
|
|
44
|
+
end
|
|
42
45
|
@document = xml_doc
|
|
43
46
|
## Determine default/top/root namespace
|
|
44
47
|
target_ns_href = nil
|
|
45
48
|
@document.namespaces.each do |ns_prefix, ns_href|
|
|
46
49
|
target_ns_href = ns_href if ns_prefix.nil? || ns_prefix.empty? || ns_prefix.eql?('xmlns')
|
|
47
50
|
end
|
|
48
|
-
|
|
51
|
+
if target_ns_href.nil? || target_ns_href.empty?
|
|
52
|
+
raise DocumentError.new("Unable to determine a default (xmlns) namespace!")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
## Determine schema locations, optionally inheriting their location declarations from a parent document
|
|
56
|
+
schema_locations = parent_xml_doc.nil? ? {} : self.class.find_schema_locations(parent_xml_doc)
|
|
57
|
+
schema_locations.merge!(self.class.find_schema_locations(@document))
|
|
58
|
+
|
|
59
|
+
## If we still don't have a file location for the target namespace, attempt to look for
|
|
60
|
+
## one based on the name of the root node (assuming that where the namespace was declared).
|
|
61
|
+
if !schema_locations.include?(target_ns_href) &&
|
|
62
|
+
@document.root.namespace.href.eql?(target_ns_href)
|
|
63
|
+
root_file_xsd = "#{@document.root.name}.xsd"
|
|
64
|
+
schema_locations[target_ns_href] = root_file_xsd if File.exist?(root_file_xsd)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
unless schema_locations.include?(target_ns_href)
|
|
68
|
+
## XXX - Another possibility would be to default to a file named after the node name declaring the xmlns
|
|
69
|
+
raise DocumentError.new("Unable to locate a source/file for the default (xmlns) namespace schema!")
|
|
70
|
+
end
|
|
71
|
+
|
|
49
72
|
## Build an all-in-one XSD document that imports all of the separate schema locations
|
|
50
73
|
@xsd = "<?xml version=\"1.0\"?>\n"
|
|
51
74
|
@xsd << "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
|
|
52
75
|
" targetNamespace=\"#{target_ns_href}\"\n" \
|
|
53
76
|
" version=\"1.0\">\n"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
raise DocumentError.new("MISMATCHING namespace: #{ns_set.first} -> #{ns_loc} VS #{ns_set.last}")
|
|
63
|
-
end
|
|
64
|
-
else
|
|
65
|
-
schemata_by_ns[ns_set.first] = ns_set.last
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
schemata_by_ns.each do |ns_href, ns_file|
|
|
70
|
-
@xsd << (ns_href.eql?(target_ns_href) ?
|
|
71
|
-
" <xsd:include schemaLocation=\"#{ns_file}\"/>\n" :
|
|
72
|
-
" <xsd:import namespace=\"#{ns_href}\" schemaLocation=\"#{ns_file}\"/>\n")
|
|
77
|
+
|
|
78
|
+
## Minimally we need the target namespace location or we have nothing to include
|
|
79
|
+
target_ns_file = schema_locations.delete(target_ns_href)
|
|
80
|
+
@xsd << " <xsd:include schemaLocation=\"#{target_ns_file}\"/>\n" unless target_ns_file.nil?
|
|
81
|
+
|
|
82
|
+
## Now add imports for the other defined schemaLocations
|
|
83
|
+
schema_locations.each do |ns_href, ns_file|
|
|
84
|
+
@xsd << " <xsd:import namespace=\"#{ns_href}\" schemaLocation=\"#{ns_file}\"/>\n"
|
|
73
85
|
end
|
|
74
86
|
@xsd << "</xsd:schema>\n"
|
|
75
87
|
|
|
@@ -89,5 +101,32 @@ class XML_XSI
|
|
|
89
101
|
end
|
|
90
102
|
errors
|
|
91
103
|
end
|
|
104
|
+
|
|
105
|
+
def self.find_schema_locations(xml_doc)
|
|
106
|
+
## Include the default xml namespace
|
|
107
|
+
schema_locations = {}
|
|
108
|
+
|
|
109
|
+
## Determine if the document has reference to the namespace "http://www.w3.org/2001/XMLSchema-instance"
|
|
110
|
+
## which is used for defining schemaLocations
|
|
111
|
+
xsi_prefix = xml_doc.namespaces.invert['http://www.w3.org/2001/XMLSchema-instance']&.delete_prefix('xmlns:')
|
|
112
|
+
|
|
113
|
+
## Iterate over all the elements and find any xsi:schemaLocation attributes
|
|
114
|
+
## and build a hash of all of the namespaces and locations
|
|
115
|
+
unless xsi_prefix.nil?
|
|
116
|
+
xsi_loc = "#{xsi_prefix}:schemaLocation"
|
|
117
|
+
xml_doc.search("//*[@#{xsi_loc}]").each do |elem|
|
|
118
|
+
elem[xsi_loc].scan(/(\S+)\s+(\S+)/).each do |ns_set|
|
|
119
|
+
if ns_loc = schema_locations[ns_set.first]
|
|
120
|
+
unless ns_loc.eql?(ns_set.last)
|
|
121
|
+
raise DocumentError.new("MISMATCHING namespace: #{ns_set.first} -> #{ns_loc} VS #{ns_set.last}")
|
|
122
|
+
end
|
|
123
|
+
else
|
|
124
|
+
schema_locations[ns_set.first] = ns_set.last
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
schema_locations
|
|
130
|
+
end
|
|
92
131
|
end
|
|
93
132
|
end
|
data/validate_xml_xsi.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: validate_xml_xsi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Hansen
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -52,7 +51,6 @@ dependencies:
|
|
|
52
51
|
- - ">="
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: 1.13.2
|
|
55
|
-
description:
|
|
56
54
|
email:
|
|
57
55
|
- david@hansen4.net
|
|
58
56
|
executables:
|
|
@@ -76,7 +74,6 @@ metadata:
|
|
|
76
74
|
homepage_uri: https://github.com/d-hansen/validate_xml_xsi
|
|
77
75
|
source_code_uri: https://github.com/d-hansen/validate_xml_xsi
|
|
78
76
|
changelog_uri: https://github.com/d-hansen/validate_xml_xsi/blob/master/CHANGELOG.md
|
|
79
|
-
post_install_message:
|
|
80
77
|
rdoc_options: []
|
|
81
78
|
require_paths:
|
|
82
79
|
- lib
|
|
@@ -91,8 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
91
88
|
- !ruby/object:Gem::Version
|
|
92
89
|
version: '0'
|
|
93
90
|
requirements: []
|
|
94
|
-
rubygems_version:
|
|
95
|
-
signing_key:
|
|
91
|
+
rubygems_version: 4.0.2
|
|
96
92
|
specification_version: 4
|
|
97
93
|
summary: Validate XML against it's embedded XSI elements that define the XSD's.
|
|
98
94
|
test_files: []
|