lutaml-model 0.3.5 → 0.3.7
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 +119 -12
- data/README.adoc +430 -21
- data/lib/lutaml/model/attribute.rb +27 -0
- data/lib/lutaml/model/config.rb +82 -1
- data/lib/lutaml/model/error/unknown_adapter_type_error.rb +16 -0
- data/lib/lutaml/model/error.rb +1 -0
- data/lib/lutaml/model/serialize.rb +75 -126
- data/lib/lutaml/model/type.rb +0 -24
- data/lib/lutaml/model/utils.rb +45 -0
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +73 -0
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +89 -0
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +16 -90
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +14 -93
- data/lib/lutaml/model/xml_adapter/xml_document.rb +89 -0
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +0 -12
- data/lib/lutaml/model.rb +3 -2
- metadata +6 -3
- data/lib/lutaml/model/type/json.rb +0 -34
@@ -13,8 +13,6 @@ require_relative "comparable_model"
|
|
13
13
|
module Lutaml
|
14
14
|
module Model
|
15
15
|
module Serialize
|
16
|
-
FORMATS = %i[xml json yaml toml].freeze
|
17
|
-
|
18
16
|
include ComparableModel
|
19
17
|
|
20
18
|
def self.included(base)
|
@@ -73,7 +71,7 @@ module Lutaml
|
|
73
71
|
attr.options[:values].include?(value)
|
74
72
|
end
|
75
73
|
|
76
|
-
|
74
|
+
Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
|
77
75
|
define_method(format) do |&block|
|
78
76
|
klass = format == :xml ? XmlMapping : KeyValueMapping
|
79
77
|
mappings[format] = klass.new
|
@@ -87,9 +85,8 @@ module Lutaml
|
|
87
85
|
define_method(:"from_#{format}") do |data|
|
88
86
|
adapter = Lutaml::Model::Config.send(:"#{format}_adapter")
|
89
87
|
doc = adapter.parse(data)
|
90
|
-
|
91
|
-
|
92
|
-
generate_model_object(self, mapped_attrs)
|
88
|
+
|
89
|
+
apply_mappings(doc.to_h, format)
|
93
90
|
end
|
94
91
|
|
95
92
|
define_method(:"to_#{format}") do |instance|
|
@@ -120,13 +117,14 @@ module Lutaml
|
|
120
117
|
name = rule.to
|
121
118
|
next if except&.include?(name) || (only && !only.include?(name))
|
122
119
|
|
123
|
-
next handle_delegate(instance, rule, hash) if rule.delegate
|
120
|
+
next handle_delegate(instance, rule, hash, format) if rule.delegate
|
124
121
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
122
|
+
if rule.custom_methods[:to]
|
123
|
+
next instance.send(rule.custom_methods[:to], instance,
|
124
|
+
hash)
|
125
|
+
end
|
126
|
+
|
127
|
+
value = instance.send(name)
|
130
128
|
|
131
129
|
next if value.nil? && !rule.render_nil
|
132
130
|
|
@@ -134,68 +132,27 @@ module Lutaml
|
|
134
132
|
|
135
133
|
hash[rule.from] = if rule.child_mappings
|
136
134
|
generate_hash_from_child_mappings(value, rule.child_mappings)
|
137
|
-
elsif value.is_a?(Array)
|
138
|
-
value.map do |v|
|
139
|
-
if attribute.type <= Serialize
|
140
|
-
attribute.type.hash_representation(v, format, options)
|
141
|
-
else
|
142
|
-
attribute.type.serialize(v)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
elsif attribute.type <= Serialize
|
146
|
-
attribute.type.hash_representation(value, format, options)
|
147
135
|
else
|
148
|
-
attribute.
|
136
|
+
attribute.serialize(value, format, options)
|
149
137
|
end
|
150
138
|
end
|
151
139
|
end
|
152
140
|
|
153
|
-
def handle_delegate(instance, rule, hash)
|
141
|
+
def handle_delegate(instance, rule, hash, format)
|
154
142
|
name = rule.to
|
155
143
|
value = instance.send(rule.delegate).send(name)
|
156
144
|
return if value.nil? && !rule.render_nil
|
157
145
|
|
158
146
|
attribute = instance.send(rule.delegate).class.attributes[name]
|
159
|
-
hash[rule.from] =
|
160
|
-
when Array
|
161
|
-
value.map do |v|
|
162
|
-
if v.is_a?(Serialize)
|
163
|
-
hash_representation(v, format, options)
|
164
|
-
else
|
165
|
-
attribute.type.serialize(v)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
else
|
169
|
-
if value.is_a?(Serialize)
|
170
|
-
hash_representation(value, format, options)
|
171
|
-
else
|
172
|
-
attribute.type.serialize(value)
|
173
|
-
end
|
174
|
-
end
|
147
|
+
hash[rule.from] = attribute.serialize(value, format)
|
175
148
|
end
|
176
149
|
|
177
150
|
def mappings_for(format)
|
178
151
|
mappings[format] || default_mappings(format)
|
179
152
|
end
|
180
153
|
|
181
|
-
def generate_model_object(type, mapped_attrs)
|
182
|
-
return type.model.new(mapped_attrs) if self == model
|
183
|
-
|
184
|
-
instance = type.model.new
|
185
|
-
|
186
|
-
type.attributes.each do |name, attr|
|
187
|
-
value = attr_value(mapped_attrs, name, attr)
|
188
|
-
|
189
|
-
instance.send(:"#{name}=", ensure_utf8(value))
|
190
|
-
end
|
191
|
-
|
192
|
-
instance
|
193
|
-
end
|
194
|
-
|
195
154
|
def attr_value(attrs, name, attr_rule)
|
196
|
-
value = if attrs.key?(name)
|
197
|
-
attrs[name]
|
198
|
-
elsif attrs.key?(name.to_sym)
|
155
|
+
value = if attrs.key?(name.to_sym)
|
199
156
|
attrs[name.to_sym]
|
200
157
|
elsif attrs.key?(name.to_s)
|
201
158
|
attrs[name.to_s]
|
@@ -213,8 +170,6 @@ module Lutaml
|
|
213
170
|
Lutaml::Model::Type.cast(v, attr_rule.type)
|
214
171
|
end
|
215
172
|
end
|
216
|
-
elsif value.is_a?(Hash) && attr_rule.type != Lutaml::Model::Type::Hash
|
217
|
-
generate_model_object(attr_rule.type, value)
|
218
173
|
else
|
219
174
|
# TODO: This code is problematic because Type.cast does not know
|
220
175
|
# about all the types.
|
@@ -281,11 +236,12 @@ module Lutaml
|
|
281
236
|
hash
|
282
237
|
end
|
283
238
|
|
284
|
-
def apply_mappings(doc, format)
|
285
|
-
|
239
|
+
def apply_mappings(doc, format, options = {})
|
240
|
+
instance = options[:instance] || model.new
|
241
|
+
return apply_xml_mapping(doc, instance, options) if format == :xml
|
286
242
|
|
287
243
|
mappings = mappings_for(format).mappings
|
288
|
-
mappings.
|
244
|
+
mappings.each do |rule|
|
289
245
|
attr = if rule.delegate
|
290
246
|
attributes[rule.delegate].type.attributes[rule.to]
|
291
247
|
else
|
@@ -294,50 +250,51 @@ module Lutaml
|
|
294
250
|
|
295
251
|
raise "Attribute '#{rule.to}' not found in #{self}" unless attr
|
296
252
|
|
297
|
-
value = if rule.
|
298
|
-
new.send(rule.custom_methods[:from], hash, doc)
|
299
|
-
elsif doc.key?(rule.name) || doc.key?(rule.name.to_sym)
|
253
|
+
value = if doc.key?(rule.name) || doc.key?(rule.name.to_sym)
|
300
254
|
doc[rule.name] || doc[rule.name.to_sym]
|
301
255
|
else
|
302
256
|
attr.default
|
303
257
|
end
|
304
258
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
value = (value || []).map do |v|
|
309
|
-
attr.type <= Serialize ? attr.type.apply_mappings(v, format) : v
|
310
|
-
end
|
311
|
-
elsif value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
|
312
|
-
value = attr.type.apply_mappings(value, format)
|
259
|
+
if rule.custom_methods[:from]
|
260
|
+
value = new.send(rule.custom_methods[:from], instance, value)
|
261
|
+
next
|
313
262
|
end
|
314
263
|
|
264
|
+
value = apply_child_mappings(value, rule.child_mappings)
|
265
|
+
value = attr.cast(value, format)
|
266
|
+
|
315
267
|
if rule.delegate
|
316
|
-
|
317
|
-
|
268
|
+
if instance.public_send(rule.delegate).nil?
|
269
|
+
instance.public_send(:"#{rule.delegate}=",
|
270
|
+
attributes[rule.delegate].type.new)
|
271
|
+
end
|
272
|
+
instance.public_send(rule.delegate).public_send(:"#{rule.to}=",
|
273
|
+
value)
|
318
274
|
else
|
319
|
-
|
275
|
+
instance.public_send(:"#{rule.to}=", value)
|
320
276
|
end
|
321
277
|
end
|
278
|
+
|
279
|
+
instance
|
322
280
|
end
|
323
281
|
|
324
|
-
def apply_xml_mapping(doc,
|
325
|
-
return unless doc
|
282
|
+
def apply_xml_mapping(doc, instance, options = {})
|
283
|
+
return instance unless doc
|
326
284
|
|
327
285
|
mappings = mappings_for(:xml).mappings
|
328
286
|
|
329
287
|
if doc.is_a?(Array)
|
330
288
|
raise "May be `collection: true` is" \
|
331
|
-
"missing for #{self} in #{caller_class}"
|
289
|
+
"missing for #{self} in #{options[:caller_class]}"
|
332
290
|
end
|
333
291
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
mapping_from = []
|
292
|
+
if instance.respond_to?(:ordered=)
|
293
|
+
instance.element_order = doc.item_order
|
294
|
+
instance.ordered = mappings_for(:xml).mixed_content? || options[:mixed_content]
|
295
|
+
end
|
339
296
|
|
340
|
-
mappings.
|
297
|
+
mappings.each do |rule|
|
341
298
|
attr = attributes[rule.to]
|
342
299
|
raise "Attribute '#{rule.to}' not found in #{self}" unless attr
|
343
300
|
|
@@ -348,52 +305,38 @@ module Lutaml
|
|
348
305
|
doc[rule.name.to_s] || doc[rule.name.to_sym]
|
349
306
|
end
|
350
307
|
|
351
|
-
if
|
352
|
-
|
353
|
-
|
308
|
+
if value.is_a?(Array)
|
309
|
+
value = value.map do |v|
|
310
|
+
v.is_a?(Hash) && !(attr.type <= Serialize) ? v["text"] : v
|
354
311
|
end
|
355
|
-
|
356
|
-
value =
|
357
|
-
if attr.type <= Serialize
|
358
|
-
attr.type.apply_xml_mapping(v, caller_class: self, mixed_content: rule.mixed_content)
|
359
|
-
elsif v.is_a?(Hash)
|
360
|
-
v["text"]
|
361
|
-
else
|
362
|
-
v
|
363
|
-
end
|
364
|
-
end
|
365
|
-
elsif attr.type <= Serialize
|
366
|
-
value = attr.type.apply_xml_mapping(value, caller_class: self, mixed_content: rule.mixed_content)
|
367
|
-
else
|
368
|
-
if value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
|
369
|
-
value = value["text"]
|
370
|
-
end
|
371
|
-
|
372
|
-
value = attr.type.cast(value) unless is_content_mapping
|
312
|
+
elsif !(attr.type <= Serialize) && value.is_a?(Hash) && attr.type != Lutaml::Model::Type::Hash
|
313
|
+
value = value["text"]
|
373
314
|
end
|
374
315
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
else
|
384
|
-
mapping_hash[rule.to]
|
385
|
-
end
|
316
|
+
unless is_content_mapping
|
317
|
+
value = attr.cast(
|
318
|
+
value,
|
319
|
+
:xml,
|
320
|
+
caller_class: self,
|
321
|
+
mixed_content: rule.mixed_content,
|
322
|
+
)
|
323
|
+
end
|
386
324
|
|
387
|
-
|
325
|
+
if rule.custom_methods[:from]
|
326
|
+
new.send(rule.custom_methods[:from], instance, value)
|
327
|
+
else
|
328
|
+
instance.public_send(:"#{rule.to}=", value)
|
329
|
+
end
|
388
330
|
end
|
389
331
|
|
390
|
-
|
332
|
+
instance
|
391
333
|
end
|
392
334
|
|
393
335
|
def ensure_utf8(value)
|
394
336
|
case value
|
395
337
|
when String
|
396
|
-
value.encode("UTF-8", invalid: :replace, undef: :replace,
|
338
|
+
value.encode("UTF-8", invalid: :replace, undef: :replace,
|
339
|
+
replace: "")
|
397
340
|
when Array
|
398
341
|
value.map { |v| ensure_utf8(v) }
|
399
342
|
when Hash
|
@@ -408,7 +351,7 @@ module Lutaml
|
|
408
351
|
end
|
409
352
|
end
|
410
353
|
|
411
|
-
|
354
|
+
attr_accessor :element_order
|
412
355
|
|
413
356
|
def initialize(attrs = {})
|
414
357
|
return unless self.class.attributes
|
@@ -431,22 +374,27 @@ module Lutaml
|
|
431
374
|
@ordered
|
432
375
|
end
|
433
376
|
|
377
|
+
def ordered=(ordered)
|
378
|
+
@ordered = ordered
|
379
|
+
end
|
380
|
+
|
434
381
|
def key_exist?(hash, key)
|
435
|
-
hash.key?(key
|
382
|
+
hash.key?(key.to_sym) || hash.key?(key.to_s)
|
436
383
|
end
|
437
384
|
|
438
385
|
def key_value(hash, key)
|
439
|
-
hash[key
|
386
|
+
hash[key.to_sym] || hash[key.to_s]
|
440
387
|
end
|
441
388
|
|
442
|
-
|
389
|
+
Lutaml::Model::Config::AVAILABLE_FORMATS.each do |format|
|
443
390
|
define_method(:"to_#{format}") do |options = {}|
|
444
391
|
validate
|
445
392
|
adapter = Lutaml::Model::Config.public_send(:"#{format}_adapter")
|
446
393
|
representation = if format == :xml
|
447
394
|
self
|
448
395
|
else
|
449
|
-
self.class.hash_representation(self, format,
|
396
|
+
self.class.hash_representation(self, format,
|
397
|
+
options)
|
450
398
|
end
|
451
399
|
|
452
400
|
adapter.new(representation).public_send(:"to_#{format}", options)
|
@@ -457,7 +405,8 @@ module Lutaml
|
|
457
405
|
self.class.attributes.each do |name, attr|
|
458
406
|
value = send(name)
|
459
407
|
unless self.class.attr_value_valid?(name, value)
|
460
|
-
raise Lutaml::Model::InvalidValueError.new(name, value,
|
408
|
+
raise Lutaml::Model::InvalidValueError.new(name, value,
|
409
|
+
attr.options[:values])
|
461
410
|
end
|
462
411
|
end
|
463
412
|
end
|
data/lib/lutaml/model/type.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
require "date"
|
2
2
|
require "bigdecimal"
|
3
|
-
require "securerandom"
|
4
|
-
require "uri"
|
5
|
-
require "ipaddr"
|
6
3
|
|
7
4
|
module Lutaml
|
8
5
|
module Model
|
@@ -20,12 +17,6 @@ module Lutaml
|
|
20
17
|
Boolean
|
21
18
|
Decimal
|
22
19
|
Hash
|
23
|
-
Uuid
|
24
|
-
Symbol
|
25
|
-
Binary
|
26
|
-
Url
|
27
|
-
IpAddress
|
28
|
-
Json
|
29
20
|
).each do |t|
|
30
21
|
class_eval <<~HEREDOC, __FILE__, __LINE__ + 1
|
31
22
|
class #{t} # class Integer
|
@@ -72,18 +63,6 @@ module Lutaml
|
|
72
63
|
BigDecimal(value.to_s)
|
73
64
|
when "Hash"
|
74
65
|
normalize_hash(Hash(value))
|
75
|
-
when "Uuid"
|
76
|
-
UUID_REGEX.match?(value) ? value : SecureRandom.uuid
|
77
|
-
when "Symbol"
|
78
|
-
value.to_sym
|
79
|
-
when "Binary"
|
80
|
-
value.force_encoding("BINARY")
|
81
|
-
when "Url"
|
82
|
-
URI.parse(value.to_s)
|
83
|
-
when "IpAddress"
|
84
|
-
IPAddr.new(value.to_s)
|
85
|
-
when "Json"
|
86
|
-
Json.cast(value)
|
87
66
|
else
|
88
67
|
value
|
89
68
|
end
|
@@ -107,8 +86,6 @@ module Lutaml
|
|
107
86
|
value.to_s("F")
|
108
87
|
when "Hash"
|
109
88
|
Hash(value)
|
110
|
-
when "Json"
|
111
|
-
value.to_json
|
112
89
|
else
|
113
90
|
value.to_s
|
114
91
|
end
|
@@ -145,4 +122,3 @@ end
|
|
145
122
|
|
146
123
|
require_relative "type/time_without_date"
|
147
124
|
require_relative "type/date_time"
|
148
|
-
require_relative "type/json"
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module Utils
|
6
|
+
class << self
|
7
|
+
# Convert string to camel case
|
8
|
+
def camel_case(str)
|
9
|
+
return "" if str.nil? || str.empty?
|
10
|
+
|
11
|
+
str.split("/").map { |part| camelize_part(part) }.join("::")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convert string to class name
|
15
|
+
def classify(str)
|
16
|
+
str = str.to_s.delete(".")
|
17
|
+
str = str.sub(/^[a-z\d]*/) { |match| camel_case(match) || match }
|
18
|
+
|
19
|
+
str.gsub("::", "/").gsub(%r{(?:_|-|(/))([a-z\d]*)}i) do
|
20
|
+
word = Regexp.last_match(2)
|
21
|
+
substituted = camel_case(word) || word
|
22
|
+
Regexp.last_match(1) ? "::#{substituted}" : substituted
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Convert string to snake case
|
27
|
+
def snake_case(str)
|
28
|
+
str = str.to_s.tr(".", "_")
|
29
|
+
return str unless /[A-Z-]|::/.match?(str)
|
30
|
+
|
31
|
+
str.gsub("::", "/")
|
32
|
+
.gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) { "#{$1 || $2}_" }
|
33
|
+
.tr("-", "_")
|
34
|
+
.downcase
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def camelize_part(part)
|
40
|
+
part.gsub(/(?:_|-|^)([a-z\d])/i) { $1.upcase }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module XmlAdapter
|
4
|
+
module Builder
|
5
|
+
class Nokogiri
|
6
|
+
def self.build(options = {})
|
7
|
+
if block_given?
|
8
|
+
::Nokogiri::XML::Builder.new(options) do |xml|
|
9
|
+
yield(new(xml))
|
10
|
+
end
|
11
|
+
else
|
12
|
+
new(::Nokogiri::XML::Builder.new(options))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :xml
|
17
|
+
|
18
|
+
def initialize(xml)
|
19
|
+
@xml = xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_element(name, attributes = {})
|
23
|
+
xml.doc.create_element(name, attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_element(element, child)
|
27
|
+
element.add_child(child)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_and_add_element(element_name, prefix: nil, attributes: {})
|
31
|
+
add_namespace_prefix(prefix) if prefix
|
32
|
+
|
33
|
+
if block_given?
|
34
|
+
public_send(element_name, attributes) do
|
35
|
+
yield(self)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
public_send(element_name, attributes)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_text(element, text)
|
43
|
+
if element.is_a?(self.class)
|
44
|
+
element = element.xml.parent
|
45
|
+
end
|
46
|
+
|
47
|
+
add_element(element, ::Nokogiri::XML::Text.new(text.to_s, xml.doc))
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_namespace_prefix(prefix)
|
51
|
+
xml[prefix] if prefix
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method_name, *args)
|
57
|
+
if block_given?
|
58
|
+
xml.public_send(method_name, *args) do
|
59
|
+
yield(xml)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
xml.public_send(method_name, *args)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def respond_to_missing?(method_name, include_private = false)
|
67
|
+
xml.respond_to?(method_name) || super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
module XmlAdapter
|
4
|
+
module Builder
|
5
|
+
class Ox
|
6
|
+
def self.build(options = {})
|
7
|
+
if block_given?
|
8
|
+
::Ox::Builder.new(options) do |xml|
|
9
|
+
yield(new(xml))
|
10
|
+
end
|
11
|
+
else
|
12
|
+
new(::Ox::Builder.new(options))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :xml
|
17
|
+
|
18
|
+
def initialize(xml)
|
19
|
+
@xml = xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_element(name, attributes = {})
|
23
|
+
if block_given?
|
24
|
+
xml.element(name, attributes) do |element|
|
25
|
+
yield(self.class.new(element))
|
26
|
+
end
|
27
|
+
else
|
28
|
+
xml.element(name, attributes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_element(element, child)
|
33
|
+
element << child
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_and_add_element(element_name, prefix: nil, attributes: {})
|
37
|
+
prefixed_name = if prefix
|
38
|
+
"#{prefix}:#{element_name}"
|
39
|
+
else
|
40
|
+
element_name
|
41
|
+
end
|
42
|
+
|
43
|
+
if block_given?
|
44
|
+
xml.element(prefixed_name, attributes) do |element|
|
45
|
+
yield(self.class.new(element))
|
46
|
+
end
|
47
|
+
else
|
48
|
+
xml.element(prefixed_name, attributes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def <<(text)
|
53
|
+
xml.text(text)
|
54
|
+
end
|
55
|
+
|
56
|
+
def add_text(element, text)
|
57
|
+
element << text
|
58
|
+
end
|
59
|
+
|
60
|
+
# Add XML namespace to document
|
61
|
+
#
|
62
|
+
# Ox doesn't support XML namespaces so this method does nothing.
|
63
|
+
def add_namespace_prefix(_prefix)
|
64
|
+
# :noop:
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def parent
|
69
|
+
xml
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(method_name, *args)
|
73
|
+
if block_given?
|
74
|
+
xml.public_send(method_name, *args) do
|
75
|
+
yield(xml)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
xml.public_send(method_name, *args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing?(method_name, include_private = false)
|
83
|
+
xml.respond_to?(method_name) || super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|