shale 0.3.0 → 0.5.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 +31 -0
- data/README.md +200 -21
- data/exe/shaleb +108 -36
- data/lib/shale/adapter/nokogiri/document.rb +87 -0
- data/lib/shale/adapter/nokogiri/node.rb +100 -0
- data/lib/shale/adapter/nokogiri.rb +11 -151
- data/lib/shale/adapter/ox/document.rb +80 -0
- data/lib/shale/adapter/ox/node.rb +88 -0
- data/lib/shale/adapter/ox.rb +9 -134
- data/lib/shale/adapter/rexml/document.rb +88 -0
- data/lib/shale/adapter/rexml/node.rb +99 -0
- data/lib/shale/adapter/rexml.rb +9 -150
- data/lib/shale/attribute.rb +6 -0
- data/lib/shale/error.rb +39 -0
- data/lib/shale/mapper.rb +8 -6
- data/lib/shale/schema/compiler/boolean.rb +21 -0
- data/lib/shale/schema/compiler/complex.rb +88 -0
- data/lib/shale/schema/compiler/date.rb +21 -0
- data/lib/shale/schema/compiler/float.rb +21 -0
- data/lib/shale/schema/compiler/integer.rb +21 -0
- data/lib/shale/schema/compiler/property.rb +70 -0
- data/lib/shale/schema/compiler/string.rb +21 -0
- data/lib/shale/schema/compiler/time.rb +21 -0
- data/lib/shale/schema/compiler/value.rb +21 -0
- data/lib/shale/schema/compiler/xml_complex.rb +50 -0
- data/lib/shale/schema/compiler/xml_property.rb +73 -0
- data/lib/shale/schema/json_compiler.rb +331 -0
- data/lib/shale/schema/{json → json_generator}/base.rb +2 -2
- data/lib/shale/schema/{json → json_generator}/boolean.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/collection.rb +2 -2
- data/lib/shale/schema/{json → json_generator}/date.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/float.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/integer.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/object.rb +5 -2
- data/lib/shale/schema/{json → json_generator}/ref.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/schema.rb +7 -5
- data/lib/shale/schema/{json → json_generator}/string.rb +1 -1
- data/lib/shale/schema/{json → json_generator}/time.rb +1 -1
- data/lib/shale/schema/json_generator/value.rb +23 -0
- data/lib/shale/schema/{json.rb → json_generator.rb} +36 -36
- data/lib/shale/schema/xml_compiler.rb +919 -0
- data/lib/shale/schema/{xml → xml_generator}/attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/complex_type.rb +5 -2
- data/lib/shale/schema/{xml → xml_generator}/element.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/import.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/ref_attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/ref_element.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/schema.rb +5 -5
- data/lib/shale/schema/{xml → xml_generator}/typed_attribute.rb +1 -1
- data/lib/shale/schema/{xml → xml_generator}/typed_element.rb +1 -1
- data/lib/shale/schema/{xml.rb → xml_generator.rb} +25 -26
- data/lib/shale/schema.rb +44 -5
- data/lib/shale/type/{composite.rb → complex.rb} +34 -22
- data/lib/shale/utils.rb +42 -7
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +8 -19
- data/shale.gemspec +1 -1
- metadata +47 -27
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Adapter
|
5
|
+
module Nokogiri
|
6
|
+
# Wrapper around Nokogiri::XML::Node API
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Node
|
10
|
+
# Initialize object with Nokogiri node
|
11
|
+
#
|
12
|
+
# @param [::Nokogiri::XML::Node] node Nokogiri node
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def initialize(node)
|
16
|
+
@node = node
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return namespaces defined on document
|
20
|
+
#
|
21
|
+
# @return [Hash<String, String>]
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# node.namespaces # => { 'foo' => 'http://foo.com', 'bar' => 'http://bar.com' }
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def namespaces
|
28
|
+
@node.namespaces.transform_keys { |e| e.sub('xmlns:', '') }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return name of the node in the format of
|
32
|
+
# namespace:name when the node is namespaced or just name when it's not
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
#
|
36
|
+
# @example without namespace
|
37
|
+
# node.name # => Bar
|
38
|
+
#
|
39
|
+
# @example with namespace
|
40
|
+
# node.name # => http://foo:Bar
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
def name
|
44
|
+
[@node.namespace&.href, @node.name].compact.join(':')
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return all attributes associated with the node
|
48
|
+
#
|
49
|
+
# @return [Hash]
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
def attributes
|
53
|
+
@node.attribute_nodes.each_with_object({}) do |node, hash|
|
54
|
+
name = [node.namespace&.href, node.name].compact.join(':')
|
55
|
+
hash[name] = node.value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return node's parent
|
60
|
+
#
|
61
|
+
# @return [Shale::Adapter::Nokogiri::Node, nil]
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def parent
|
65
|
+
if @node.respond_to?(:parent) && @node.parent && @node.parent.name != 'document'
|
66
|
+
self.class.new(@node.parent)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return node's element children
|
71
|
+
#
|
72
|
+
# @return [Array<Shale::Adapter::Nokogiri::Node>]
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
def children
|
76
|
+
@node
|
77
|
+
.children
|
78
|
+
.to_a
|
79
|
+
.filter(&:element?)
|
80
|
+
.map { |e| self.class.new(e) }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Return first text child of a node
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
def text
|
89
|
+
first = @node
|
90
|
+
.children
|
91
|
+
.to_a
|
92
|
+
.filter(&:text?)
|
93
|
+
.first
|
94
|
+
|
95
|
+
first&.text
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'nokogiri'
|
4
4
|
|
5
|
+
require_relative '../error'
|
6
|
+
require_relative 'nokogiri/document'
|
7
|
+
require_relative 'nokogiri/node'
|
8
|
+
|
5
9
|
module Shale
|
6
10
|
module Adapter
|
7
11
|
# Nokogiri adapter
|
@@ -12,7 +16,9 @@ module Shale
|
|
12
16
|
#
|
13
17
|
# @param [String] xml XML document
|
14
18
|
#
|
15
|
-
# @
|
19
|
+
# @raise [ParseError] when XML document has errors
|
20
|
+
#
|
21
|
+
# @return [Shale::Adapter::Nokogiri::Node]
|
16
22
|
#
|
17
23
|
# @api private
|
18
24
|
def self.load(xml)
|
@@ -20,6 +26,10 @@ module Shale
|
|
20
26
|
config.noblanks
|
21
27
|
end
|
22
28
|
|
29
|
+
unless doc.errors.empty?
|
30
|
+
raise ParseError, "Document is invalid: #{doc.errors}"
|
31
|
+
end
|
32
|
+
|
23
33
|
Node.new(doc.root)
|
24
34
|
end
|
25
35
|
|
@@ -57,156 +67,6 @@ module Shale
|
|
57
67
|
def self.create_document
|
58
68
|
Document.new
|
59
69
|
end
|
60
|
-
|
61
|
-
# Wrapper around Nokogiri API
|
62
|
-
#
|
63
|
-
# @api private
|
64
|
-
class Document
|
65
|
-
# Initialize object
|
66
|
-
#
|
67
|
-
# @api private
|
68
|
-
def initialize
|
69
|
-
@doc = ::Nokogiri::XML::Document.new
|
70
|
-
@namespaces = {}
|
71
|
-
end
|
72
|
-
|
73
|
-
# Return Nokogiri document
|
74
|
-
#
|
75
|
-
# @return [::Nokogiri::XML::Document]
|
76
|
-
#
|
77
|
-
# @api private
|
78
|
-
def doc
|
79
|
-
if @doc.root
|
80
|
-
@namespaces.each do |prefix, namespace|
|
81
|
-
@doc.root.add_namespace(prefix, namespace)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
@doc
|
86
|
-
end
|
87
|
-
|
88
|
-
# Create Nokogiri element
|
89
|
-
#
|
90
|
-
# @param [String] name Name of the XML element
|
91
|
-
#
|
92
|
-
# @return [::Nokogiri::XML::Element]
|
93
|
-
#
|
94
|
-
# @api private
|
95
|
-
def create_element(name)
|
96
|
-
::Nokogiri::XML::Element.new(name, @doc)
|
97
|
-
end
|
98
|
-
|
99
|
-
# Add XML namespace to document
|
100
|
-
#
|
101
|
-
# @param [String] prefix
|
102
|
-
# @param [String] namespace
|
103
|
-
#
|
104
|
-
# @api private
|
105
|
-
def add_namespace(prefix, namespace)
|
106
|
-
@namespaces[prefix] = namespace if prefix && namespace
|
107
|
-
end
|
108
|
-
|
109
|
-
# Add attribute to Nokogiri element
|
110
|
-
#
|
111
|
-
# @param [::Nokogiri::XML::Element] element Nokogiri element
|
112
|
-
# @param [String] name Name of the XML attribute
|
113
|
-
# @param [String] value Value of the XML attribute
|
114
|
-
#
|
115
|
-
# @api private
|
116
|
-
def add_attribute(element, name, value)
|
117
|
-
element[name] = value
|
118
|
-
end
|
119
|
-
|
120
|
-
# Add child element to Nokogiri element
|
121
|
-
#
|
122
|
-
# @param [::Nokogiri::XML::Element] element Nokogiri parent element
|
123
|
-
# @param [::Nokogiri::XML::Element] child Nokogiri child element
|
124
|
-
#
|
125
|
-
# @api private
|
126
|
-
def add_element(element, child)
|
127
|
-
element.add_child(child)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Add text node to Nokogiri element
|
131
|
-
#
|
132
|
-
# @param [::Nokogiri::XML::Element] element Nokogiri element
|
133
|
-
# @param [String] text Text to add
|
134
|
-
#
|
135
|
-
# @api private
|
136
|
-
def add_text(element, text)
|
137
|
-
element.content = text
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Wrapper around Nokogiri::XML::Node API
|
142
|
-
#
|
143
|
-
# @api private
|
144
|
-
class Node
|
145
|
-
# Initialize object with Nokogiri node
|
146
|
-
#
|
147
|
-
# @param [::Nokogiri::XML::Node] node Nokogiri node
|
148
|
-
#
|
149
|
-
# @api private
|
150
|
-
def initialize(node)
|
151
|
-
@node = node
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return name of the node in the format of
|
155
|
-
# namespace:name when the node is namespaced or just name when it's not
|
156
|
-
#
|
157
|
-
# @return [String]
|
158
|
-
#
|
159
|
-
# @example without namespace
|
160
|
-
# node.name # => Bar
|
161
|
-
#
|
162
|
-
# @example with namespace
|
163
|
-
# node.name # => http://foo:Bar
|
164
|
-
#
|
165
|
-
# @api private
|
166
|
-
def name
|
167
|
-
[@node.namespace&.href, @node.name].compact.join(':')
|
168
|
-
end
|
169
|
-
|
170
|
-
# Return all attributes associated with the node
|
171
|
-
#
|
172
|
-
# @return [Hash]
|
173
|
-
#
|
174
|
-
# @api private
|
175
|
-
def attributes
|
176
|
-
@node.attribute_nodes.each_with_object({}) do |node, hash|
|
177
|
-
name = [node.namespace&.href, node.name].compact.join(':')
|
178
|
-
hash[name] = node.value
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
# Return node's element children
|
183
|
-
#
|
184
|
-
# @return [Array<Shale::Adapter::Nokogiri::Node>]
|
185
|
-
#
|
186
|
-
# @api private
|
187
|
-
def children
|
188
|
-
@node
|
189
|
-
.children
|
190
|
-
.to_a
|
191
|
-
.filter(&:element?)
|
192
|
-
.map { |e| self.class.new(e) }
|
193
|
-
end
|
194
|
-
|
195
|
-
# Return first text child of a node
|
196
|
-
#
|
197
|
-
# @return [String]
|
198
|
-
#
|
199
|
-
# @api private
|
200
|
-
def text
|
201
|
-
first = @node
|
202
|
-
.children
|
203
|
-
.to_a
|
204
|
-
.filter(&:text?)
|
205
|
-
.first
|
206
|
-
|
207
|
-
first&.text
|
208
|
-
end
|
209
|
-
end
|
210
70
|
end
|
211
71
|
end
|
212
72
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Adapter
|
5
|
+
module Ox
|
6
|
+
# Wrapper around Ox API
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Document
|
10
|
+
# Return Ox document
|
11
|
+
#
|
12
|
+
# @return [::Ox::Document]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
attr_reader :doc
|
16
|
+
|
17
|
+
# Initialize object
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
def initialize
|
21
|
+
@doc = ::Ox::Document.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create Ox element
|
25
|
+
#
|
26
|
+
# @param [String] name Name of the XML element
|
27
|
+
#
|
28
|
+
# @return [::Ox::Element]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def create_element(name)
|
32
|
+
::Ox::Element.new(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Add XML namespace to document
|
36
|
+
#
|
37
|
+
# Ox doesn't support XML namespaces so this method does nothing.
|
38
|
+
#
|
39
|
+
# @param [String] prefix
|
40
|
+
# @param [String] namespace
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
def add_namespace(prefix, namespace)
|
44
|
+
# :noop:
|
45
|
+
end
|
46
|
+
|
47
|
+
# Add attribute to Ox element
|
48
|
+
#
|
49
|
+
# @param [::Ox::Element] element Ox element
|
50
|
+
# @param [String] name Name of the XML attribute
|
51
|
+
# @param [String] value Value of the XML attribute
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
def add_attribute(element, name, value)
|
55
|
+
element[name] = value
|
56
|
+
end
|
57
|
+
|
58
|
+
# Add child element to Ox element
|
59
|
+
#
|
60
|
+
# @param [::Ox::Element] element Ox parent element
|
61
|
+
# @param [::Ox::Element] child Ox child element
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def add_element(element, child)
|
65
|
+
element << child
|
66
|
+
end
|
67
|
+
|
68
|
+
# Add text node to Ox element
|
69
|
+
#
|
70
|
+
# @param [::Ox::Element] element Ox element
|
71
|
+
# @param [String] text Text to add
|
72
|
+
#
|
73
|
+
# @api private
|
74
|
+
def add_text(element, text)
|
75
|
+
element << text
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Adapter
|
5
|
+
module Ox
|
6
|
+
# Wrapper around Ox::Element API
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Node
|
10
|
+
# Initialize object with Ox element
|
11
|
+
#
|
12
|
+
# @param [::Ox::Element] node Ox element
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def initialize(node)
|
16
|
+
@node = node
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return namespaces defined on document (Not supported by Ox)
|
20
|
+
#
|
21
|
+
# @return [Hash<String, String>]
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# node.namespaces # => {}
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def namespaces
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Return name of the node in the format of
|
32
|
+
# prefix:name when the node is namespaced or just name when it's not
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
#
|
36
|
+
# @example without namespace
|
37
|
+
# node.name # => Bar
|
38
|
+
#
|
39
|
+
# @example with namespace
|
40
|
+
# node.name # => foo:Bar
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
def name
|
44
|
+
@node.name
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return all attributes associated with the node
|
48
|
+
#
|
49
|
+
# @return [Hash]
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
def attributes
|
53
|
+
@node.attributes
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return node's parent (Not supported by OX)
|
57
|
+
#
|
58
|
+
# @return [nil]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def parent
|
62
|
+
# :noop:
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return node's element children
|
66
|
+
#
|
67
|
+
# @return [Array<Shale::Adapter::Ox::Node>]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
def children
|
71
|
+
@node
|
72
|
+
.nodes
|
73
|
+
.filter { |e| e.is_a?(::Ox::Element) }
|
74
|
+
.map { |e| self.class.new(e) }
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return first text child of a node
|
78
|
+
#
|
79
|
+
# @return [String]
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def text
|
83
|
+
@node.text
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/shale/adapter/ox.rb
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'ox'
|
4
4
|
|
5
|
+
require_relative '../error'
|
6
|
+
require_relative 'ox/document'
|
7
|
+
require_relative 'ox/node'
|
8
|
+
|
5
9
|
module Shale
|
6
10
|
module Adapter
|
7
11
|
# Ox adapter
|
@@ -12,11 +16,15 @@ module Shale
|
|
12
16
|
#
|
13
17
|
# @param [String] xml XML document
|
14
18
|
#
|
15
|
-
# @
|
19
|
+
# @raise [ParseError] when XML document has errors
|
20
|
+
#
|
21
|
+
# @return [Shale::Adapter::Ox::Node]
|
16
22
|
#
|
17
23
|
# @api private
|
18
24
|
def self.load(xml)
|
19
25
|
Node.new(::Ox.parse(xml))
|
26
|
+
rescue ::Ox::ParseError => e
|
27
|
+
raise ParseError, "Document is invalid: #{e.message}"
|
20
28
|
end
|
21
29
|
|
22
30
|
# Serialize Ox document into XML
|
@@ -48,139 +56,6 @@ module Shale
|
|
48
56
|
def self.create_document
|
49
57
|
Document.new
|
50
58
|
end
|
51
|
-
|
52
|
-
# Wrapper around Ox API
|
53
|
-
#
|
54
|
-
# @api private
|
55
|
-
class Document
|
56
|
-
# Return Ox document
|
57
|
-
#
|
58
|
-
# @return [::Ox::Document]
|
59
|
-
#
|
60
|
-
# @api private
|
61
|
-
attr_reader :doc
|
62
|
-
|
63
|
-
# Initialize object
|
64
|
-
#
|
65
|
-
# @api private
|
66
|
-
def initialize
|
67
|
-
@doc = ::Ox::Document.new
|
68
|
-
end
|
69
|
-
|
70
|
-
# Create Ox element
|
71
|
-
#
|
72
|
-
# @param [String] name Name of the XML element
|
73
|
-
#
|
74
|
-
# @return [::Ox::Element]
|
75
|
-
#
|
76
|
-
# @api private
|
77
|
-
def create_element(name)
|
78
|
-
::Ox::Element.new(name)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Add XML namespace to document
|
82
|
-
#
|
83
|
-
# Ox doesn't support XML namespaces so this method does nothing.
|
84
|
-
#
|
85
|
-
# @param [String] prefix
|
86
|
-
# @param [String] namespace
|
87
|
-
#
|
88
|
-
# @api private
|
89
|
-
def add_namespace(prefix, namespace)
|
90
|
-
# :noop:
|
91
|
-
end
|
92
|
-
|
93
|
-
# Add attribute to Ox element
|
94
|
-
#
|
95
|
-
# @param [::Ox::Element] element Ox element
|
96
|
-
# @param [String] name Name of the XML attribute
|
97
|
-
# @param [String] value Value of the XML attribute
|
98
|
-
#
|
99
|
-
# @api private
|
100
|
-
def add_attribute(element, name, value)
|
101
|
-
element[name] = value
|
102
|
-
end
|
103
|
-
|
104
|
-
# Add child element to Ox element
|
105
|
-
#
|
106
|
-
# @param [::Ox::Element] element Ox parent element
|
107
|
-
# @param [::Ox::Element] child Ox child element
|
108
|
-
#
|
109
|
-
# @api private
|
110
|
-
def add_element(element, child)
|
111
|
-
element << child
|
112
|
-
end
|
113
|
-
|
114
|
-
# Add text node to Ox element
|
115
|
-
#
|
116
|
-
# @param [::Ox::Element] element Ox element
|
117
|
-
# @param [String] text Text to add
|
118
|
-
#
|
119
|
-
# @api private
|
120
|
-
def add_text(element, text)
|
121
|
-
element << text
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Wrapper around Ox::Element API
|
126
|
-
#
|
127
|
-
# @api private
|
128
|
-
class Node
|
129
|
-
# Initialize object with Ox element
|
130
|
-
#
|
131
|
-
# @param [::Ox::Element] node Ox element
|
132
|
-
#
|
133
|
-
# @api private
|
134
|
-
def initialize(node)
|
135
|
-
@node = node
|
136
|
-
end
|
137
|
-
|
138
|
-
# Return name of the node in the format of
|
139
|
-
# prefix:name when the node is namespaced or just name when it's not
|
140
|
-
#
|
141
|
-
# @return [String]
|
142
|
-
#
|
143
|
-
# @example without namespace
|
144
|
-
# node.name # => Bar
|
145
|
-
#
|
146
|
-
# @example with namespace
|
147
|
-
# node.name # => foo:Bar
|
148
|
-
#
|
149
|
-
# @api private
|
150
|
-
def name
|
151
|
-
@node.name
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return all attributes associated with the node
|
155
|
-
#
|
156
|
-
# @return [Hash]
|
157
|
-
#
|
158
|
-
# @api private
|
159
|
-
def attributes
|
160
|
-
@node.attributes
|
161
|
-
end
|
162
|
-
|
163
|
-
# Return node's element children
|
164
|
-
#
|
165
|
-
# @return [Array<Shale::Adapter::Ox::Node>]
|
166
|
-
#
|
167
|
-
# @api private
|
168
|
-
def children
|
169
|
-
@node
|
170
|
-
.nodes
|
171
|
-
.filter { |e| e.is_a?(::Ox::Element) }
|
172
|
-
.map { |e| self.class.new(e) }
|
173
|
-
end
|
174
|
-
|
175
|
-
# Return first text child of a node
|
176
|
-
#
|
177
|
-
# @return [String]
|
178
|
-
#
|
179
|
-
# @api private
|
180
|
-
def text
|
181
|
-
@node.text
|
182
|
-
end
|
183
|
-
end
|
184
59
|
end
|
185
60
|
end
|
186
61
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Adapter
|
5
|
+
module REXML
|
6
|
+
# Wrapper around REXML API
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Document
|
10
|
+
# Initialize object
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
def initialize
|
14
|
+
context = { attribute_quote: :quote, prologue_quote: :quote }
|
15
|
+
@doc = ::REXML::Document.new(nil, context)
|
16
|
+
@namespaces = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return REXML document
|
20
|
+
#
|
21
|
+
# @return [::REXML::Document]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
def doc
|
25
|
+
if @doc.root
|
26
|
+
@namespaces.each do |prefix, namespace|
|
27
|
+
@doc.root.add_namespace(prefix, namespace)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@doc
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create REXML element
|
35
|
+
#
|
36
|
+
# @param [String] name Name of the XML element
|
37
|
+
#
|
38
|
+
# @return [::REXML::Element]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def create_element(name)
|
42
|
+
::REXML::Element.new(name, nil, attribute_quote: :quote)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add XML namespace to document
|
46
|
+
#
|
47
|
+
# @param [String] prefix
|
48
|
+
# @param [String] namespace
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
def add_namespace(prefix, namespace)
|
52
|
+
@namespaces[prefix] = namespace if prefix && namespace
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add attribute to REXML element
|
56
|
+
#
|
57
|
+
# @param [::REXML::Element] element REXML element
|
58
|
+
# @param [String] name Name of the XML attribute
|
59
|
+
# @param [String] value Value of the XML attribute
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
def add_attribute(element, name, value)
|
63
|
+
element.add_attribute(name, value)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add child element to REXML element
|
67
|
+
#
|
68
|
+
# @param [::REXML::Element] element REXML parent element
|
69
|
+
# @param [::REXML::Element] child REXML child element
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def add_element(element, child)
|
73
|
+
element.add_element(child)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Add text node to REXML element
|
77
|
+
#
|
78
|
+
# @param [::REXML::Element] element REXML element
|
79
|
+
# @param [String] text Text to add
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def add_text(element, text)
|
83
|
+
element.add_text(text)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|