lutaml-model 0.3.25 → 0.3.27
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 +1 -1
- data/README.adoc +185 -2
- data/lib/lutaml/model/attribute.rb +34 -19
- data/lib/lutaml/model/error/pattern_not_matched_error.rb +17 -0
- data/lib/lutaml/model/error.rb +1 -0
- data/lib/lutaml/model/mapping_hash.rb +8 -0
- data/lib/lutaml/model/serialize.rb +4 -4
- data/lib/lutaml/model/validation.rb +2 -1
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/builder/nokogiri.rb +7 -1
- data/lib/lutaml/model/xml_adapter/builder/ox.rb +7 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +14 -5
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +18 -8
- data/lib/lutaml/model/xml_adapter/xml_document.rb +10 -9
- data/lib/lutaml/model/xml_mapping.rb +6 -2
- data/lib/lutaml/model/xml_mapping_rule.rb +7 -1
- data/spec/lutaml/model/attribute_spec.rb +27 -0
- data/spec/lutaml/model/cdata_spec.rb +520 -0
- data/spec/lutaml/model/delegation_spec.rb +2 -2
- data/spec/lutaml/model/mixed_content_spec.rb +68 -1
- data/spec/lutaml/model/serializable_validation_spec.rb +9 -4
- data/spec/lutaml/model/xml_mapping_spec.rb +68 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e00c3fab326d719d8341687a8411797d60ccaf54820380ba7a2dacead6a89792
|
4
|
+
data.tar.gz: e46c1dd3d50f6b2bea7da738d94ace488655205deb049170057490f6d1526bf8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab260d59203839c5fd9b1aa670501c1953c741fe75f0f7ab7261795c54cd19ed6de9807f9b8252c83ce9eee8cf2e6a9116087066e464ca1f35b8b46e29082351
|
7
|
+
data.tar.gz: c579a87612ce8e249edcca0c79f0ee2550d40af899e31ee2405ffdd48509e584df449c19bb3489a6871cdf4dfc08c4bc51f482422ea9a7d91f02d706d653cac6
|
data/.rubocop_todo.yml
CHANGED
data/README.adoc
CHANGED
@@ -543,8 +543,15 @@ end
|
|
543
543
|
====
|
544
544
|
|
545
545
|
|
546
|
+
=== Attribute value validation
|
547
|
+
|
548
|
+
==== General
|
549
|
+
|
550
|
+
There are several mechanisms to validate attribute values in Lutaml::Model.
|
551
|
+
|
552
|
+
|
546
553
|
[[attribute-enumeration]]
|
547
|
-
|
554
|
+
==== Values of an enumeration
|
548
555
|
|
549
556
|
An attribute can be defined as an enumeration by using the `values` directive.
|
550
557
|
|
@@ -641,6 +648,44 @@ acceptance of the newly updated component.
|
|
641
648
|
====
|
642
649
|
|
643
650
|
|
651
|
+
==== String values restricted to patterns
|
652
|
+
|
653
|
+
An attribute that accepts a string value accepts value validation using regular
|
654
|
+
expressions.
|
655
|
+
|
656
|
+
Syntax:
|
657
|
+
|
658
|
+
[source,ruby]
|
659
|
+
----
|
660
|
+
attribute :name_of_attribute, :string, pattern: /regex/
|
661
|
+
----
|
662
|
+
|
663
|
+
.Using the `pattern` option to restrict the value of an attribute
|
664
|
+
[example]
|
665
|
+
====
|
666
|
+
In this example, the `color` attribute takes hex color values such as `#ccddee`.
|
667
|
+
|
668
|
+
A regular expression can be used to validate values assigned to the attribute.
|
669
|
+
In this case, it is `/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/`.
|
670
|
+
|
671
|
+
[source,ruby]
|
672
|
+
----
|
673
|
+
class Glaze < Lutaml::Model::Serializable
|
674
|
+
attribute :color, :string, pattern: /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/
|
675
|
+
end
|
676
|
+
----
|
677
|
+
|
678
|
+
[source,ruby]
|
679
|
+
----
|
680
|
+
> Glaze.new(color: '#ff0000').color
|
681
|
+
> # "#ff0000"
|
682
|
+
> Glaze.new(color: '#ff000').color
|
683
|
+
> # Lutaml::Model::InvalidValueError: Invalid value for attribute 'color'
|
684
|
+
----
|
685
|
+
====
|
686
|
+
|
687
|
+
|
688
|
+
|
644
689
|
=== Attribute value default and rendering defaults
|
645
690
|
|
646
691
|
Specify default values for attributes using the `default` option.
|
@@ -771,7 +816,8 @@ class Person < Lutaml::Model::Serializable
|
|
771
816
|
end
|
772
817
|
----
|
773
818
|
|
774
|
-
For the following
|
819
|
+
For the following XML snippet:
|
820
|
+
|
775
821
|
[source,xml]
|
776
822
|
----
|
777
823
|
<Person>
|
@@ -1144,6 +1190,80 @@ end
|
|
1144
1190
|
====
|
1145
1191
|
|
1146
1192
|
|
1193
|
+
==== CDATA nodes
|
1194
|
+
|
1195
|
+
CDATA is an XML feature that allows the inclusion of text that may contain
|
1196
|
+
characters that are unescaped in XML.
|
1197
|
+
|
1198
|
+
While CDATA is not preferred in XML, it is sometimes necessary to handle CDATA
|
1199
|
+
nodes for both input and output.
|
1200
|
+
|
1201
|
+
NOTE: The W3C XML Recommendation explicitly encourages escaping characters over
|
1202
|
+
usage of CDATA.
|
1203
|
+
|
1204
|
+
Lutaml::Model supports the handling of CDATA nodes in XML in the following
|
1205
|
+
behavior:
|
1206
|
+
|
1207
|
+
. When an attribute contains a CDATA node with no text:
|
1208
|
+
** On reading: The node (CDATA or text) is read as its value.
|
1209
|
+
** On writing: The value is written as its native type.
|
1210
|
+
|
1211
|
+
. When an XML mapping sets `cdata: true` on `map_element` or `map_content`:
|
1212
|
+
** On reading: The node (CDATA or text) is read as its value.
|
1213
|
+
** On writing: The value is written as a CDATA node.
|
1214
|
+
|
1215
|
+
. When an XML mapping sets `cdata: false` on `map_element` or `map_content`:
|
1216
|
+
** On reading: The node (CDATA or text) is read as its value.
|
1217
|
+
** On writing: The value is written as a text node (string).
|
1218
|
+
|
1219
|
+
|
1220
|
+
Syntax:
|
1221
|
+
|
1222
|
+
[source,ruby]
|
1223
|
+
----
|
1224
|
+
xml do
|
1225
|
+
map_content to: :name_of_attribute, cdata: (true | false)
|
1226
|
+
map_element :name, to: :name, cdata: (true | false)
|
1227
|
+
end
|
1228
|
+
----
|
1229
|
+
|
1230
|
+
.Using `cdata` to map CDATA content
|
1231
|
+
[example]
|
1232
|
+
====
|
1233
|
+
The following class will parse the XML snippet below:
|
1234
|
+
|
1235
|
+
[source,ruby]
|
1236
|
+
----
|
1237
|
+
class Example < Lutaml::Model::Serializable
|
1238
|
+
attribute :name, :string
|
1239
|
+
attribute :description, :string
|
1240
|
+
attribute :title, :string
|
1241
|
+
attribute :note, :string
|
1242
|
+
|
1243
|
+
xml do
|
1244
|
+
root 'example'
|
1245
|
+
map_element :name, to: :name, cdata: true
|
1246
|
+
map_content to: :description, cdata: true
|
1247
|
+
map_element :title, to: :title, cdata: false
|
1248
|
+
map_element :note, to: :note, cdata: false
|
1249
|
+
end
|
1250
|
+
end
|
1251
|
+
----
|
1252
|
+
|
1253
|
+
[source,xml]
|
1254
|
+
----
|
1255
|
+
<example><name><![CDATA[John]]></name><![CDATA[here is the description]]><title><![CDATA[Lutaml]]></title><note>Careful</note></example>
|
1256
|
+
----
|
1257
|
+
|
1258
|
+
[source,ruby]
|
1259
|
+
----
|
1260
|
+
> Example.from_xml(xml)
|
1261
|
+
> #<Example:0x0000000104ac7240 @name="John" @description="here is the description" @title="Lutaml" @note="Careful">
|
1262
|
+
> Example.new(name: "John", description: "here is the description", title: "Lutaml", note: "Careful").to_xml
|
1263
|
+
> #<example><name><![CDATA[John]]></name><![CDATA[here is the description]]><title>Lutaml</title><note>Careful</note></example>
|
1264
|
+
----
|
1265
|
+
====
|
1266
|
+
|
1147
1267
|
|
1148
1268
|
==== Example for mapping
|
1149
1269
|
|
@@ -1182,6 +1302,69 @@ end
|
|
1182
1302
|
====
|
1183
1303
|
|
1184
1304
|
|
1305
|
+
==== Encoding Options in XmlAdapter
|
1306
|
+
|
1307
|
+
XmlAdapter supports the encoding in the following ways:
|
1308
|
+
|
1309
|
+
. When encoding is not passed in to_xml:
|
1310
|
+
** Default encoding is UTF-8.
|
1311
|
+
|
1312
|
+
. When encoding is explicitly passed nil:
|
1313
|
+
** Encoding will be nil, show the HexCode(Nokogiri) or ASCII-8bit(Ox).
|
1314
|
+
|
1315
|
+
. When encoding is passed with some option:
|
1316
|
+
** Encoding option will be selected as passed.
|
1317
|
+
|
1318
|
+
|
1319
|
+
Syntax:
|
1320
|
+
|
1321
|
+
[source,ruby]
|
1322
|
+
----
|
1323
|
+
Example.new(description: " ∑ is my ∏ moniker µ.").to_xml
|
1324
|
+
Example.new(description: " ∑ is my ∏ moniker µ.").to_xml(encoding: nil)
|
1325
|
+
Example.new(description: " ∑ is my ∏ moniker µ.").to_xml(encoding: "ASCII")
|
1326
|
+
----
|
1327
|
+
|
1328
|
+
[example]
|
1329
|
+
====
|
1330
|
+
The following class will parse the XML snippet below:
|
1331
|
+
|
1332
|
+
[source,ruby]
|
1333
|
+
----
|
1334
|
+
class Example < Lutaml::Model::Serializable
|
1335
|
+
attribute :name, :string
|
1336
|
+
attribute :description, :string
|
1337
|
+
attribute :value, :integer
|
1338
|
+
|
1339
|
+
xml do
|
1340
|
+
root 'example'
|
1341
|
+
map_element 'name', to: :name
|
1342
|
+
map_content to: :description
|
1343
|
+
end
|
1344
|
+
end
|
1345
|
+
----
|
1346
|
+
|
1347
|
+
[source,xml]
|
1348
|
+
----
|
1349
|
+
<example><name>John & Doe</name> ∑ is my ∏ moniker µ.</example>
|
1350
|
+
----
|
1351
|
+
|
1352
|
+
[source,ruby]
|
1353
|
+
----
|
1354
|
+
> Example.from_xml(xml)
|
1355
|
+
> #<Example:0x0000000104ac7240 @name="John & Doe", @description=" ∑ is my ∏ moniker µ.">
|
1356
|
+
> Example.new(name: "John & Doe", description: " ∑ is my ∏ moniker µ.").to_xml
|
1357
|
+
> #<example><name>John & Doe</name> ∑ is my ∏ moniker µ.</example>
|
1358
|
+
|
1359
|
+
> Example.new(name: "John & Doe", description: " ∑ is my ∏ moniker µ.").to_xml(encoding: nil)
|
1360
|
+
> #<example><name>John & Doe</name> ∑ is my ∏ moniker µ.</example>
|
1361
|
+
|
1362
|
+
> Example.new(name: "John & Doe", description: " ∑ is my ∏ moniker µ.").to_xml(encoding: "ASCII")
|
1363
|
+
> #<example><name>John & Doe</name> ∑ is my ∏ moniker µ.</example>
|
1364
|
+
----
|
1365
|
+
====
|
1366
|
+
|
1367
|
+
|
1185
1368
|
==== Namespaces
|
1186
1369
|
|
1187
1370
|
[[root-namespace]]
|
@@ -9,6 +9,7 @@ module Lutaml
|
|
9
9
|
delegate
|
10
10
|
collection
|
11
11
|
values
|
12
|
+
pattern
|
12
13
|
].freeze
|
13
14
|
|
14
15
|
def initialize(name, type, options = {})
|
@@ -87,23 +88,12 @@ module Lutaml
|
|
87
88
|
cast_value(value)
|
88
89
|
end
|
89
90
|
|
90
|
-
def
|
91
|
-
|
91
|
+
def pattern
|
92
|
+
options[:pattern]
|
92
93
|
end
|
93
94
|
|
94
|
-
|
95
|
-
|
96
|
-
# Currently there are 2 validations
|
97
|
-
# 1. Value should be from the values list if they are defined
|
98
|
-
# e.g values: ["foo", "bar"] is set then any other value for this
|
99
|
-
# attribute will raise `Lutaml::Model::InvalidValueError`
|
100
|
-
#
|
101
|
-
# 2. Value count should be between the collection range if defined
|
102
|
-
# e.g if collection: 0..5 is set then the value greater then 5
|
103
|
-
# will raise `Lutaml::Model::CollectionCountOutOfRangeError`
|
104
|
-
def validate_value!(value)
|
105
|
-
valid_value!(value)
|
106
|
-
valid_collection!(value)
|
95
|
+
def enum_values
|
96
|
+
@options.key?(:values) ? @options[:values] : []
|
107
97
|
end
|
108
98
|
|
109
99
|
def valid_value!(value)
|
@@ -123,14 +113,32 @@ module Lutaml
|
|
123
113
|
options[:values].include?(value)
|
124
114
|
end
|
125
115
|
|
126
|
-
def
|
127
|
-
|
128
|
-
return true
|
116
|
+
def valid_pattern!(value)
|
117
|
+
return true unless type == Lutaml::Model::Type::String
|
118
|
+
return true unless pattern
|
119
|
+
|
120
|
+
unless pattern.match?(value)
|
121
|
+
raise Lutaml::Model::PatternNotMatchedError.new(name, pattern, value)
|
122
|
+
end
|
129
123
|
|
124
|
+
true
|
125
|
+
end
|
126
|
+
|
127
|
+
# Check if the value to be assigned is valid for the attribute
|
128
|
+
#
|
129
|
+
# Currently there are 2 validations
|
130
|
+
# 1. Value should be from the values list if they are defined
|
131
|
+
# e.g values: ["foo", "bar"] is set then any other value for this
|
132
|
+
# attribute will raise `Lutaml::Model::InvalidValueError`
|
133
|
+
#
|
134
|
+
# 2. Value count should be between the collection range if defined
|
135
|
+
# e.g if collection: 0..5 is set then the value greater then 5
|
136
|
+
# will raise `Lutaml::Model::CollectionCountOutOfRangeError`
|
137
|
+
def validate_value!(value)
|
130
138
|
# Use the default value if the value is nil
|
131
139
|
value = default if value.nil?
|
132
140
|
|
133
|
-
valid_value!(value) && valid_collection!(value)
|
141
|
+
valid_value!(value) && valid_collection!(value) && valid_pattern!(value)
|
134
142
|
end
|
135
143
|
|
136
144
|
def validate_collection_range
|
@@ -229,6 +237,13 @@ module Lutaml
|
|
229
237
|
raise StandardError,
|
230
238
|
"Invalid options given for `#{name}` #{invalid_opts}"
|
231
239
|
end
|
240
|
+
|
241
|
+
if options.key?(:pattern) && type != Lutaml::Model::Type::String
|
242
|
+
raise StandardError,
|
243
|
+
"Invalid option `pattern` given for `#{name}`, `pattern` is only allowed for :string type"
|
244
|
+
end
|
245
|
+
|
246
|
+
true
|
232
247
|
end
|
233
248
|
|
234
249
|
def validate_type!(type)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Lutaml
|
2
|
+
module Model
|
3
|
+
class PatternNotMatchedError < Error
|
4
|
+
def initialize(attr_name, pattern, value)
|
5
|
+
@attr_name = attr_name
|
6
|
+
@pattern = pattern
|
7
|
+
@value = value
|
8
|
+
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"#{@attr_name}: \"#{@value}\" does not match #{@pattern.inspect}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/lutaml/model/error.rb
CHANGED
@@ -7,6 +7,7 @@ end
|
|
7
7
|
|
8
8
|
require_relative "error/invalid_value_error"
|
9
9
|
require_relative "error/incorrect_mapping_argument_error"
|
10
|
+
require_relative "error/pattern_not_matched_error"
|
10
11
|
require_relative "error/unknown_adapter_type_error"
|
11
12
|
require_relative "error/collection_count_out_of_range_error"
|
12
13
|
require_relative "error/validation_error"
|
@@ -343,7 +343,7 @@ module Lutaml
|
|
343
343
|
value = if rule.raw_mapping?
|
344
344
|
doc.node.inner_xml
|
345
345
|
elsif rule.content_mapping?
|
346
|
-
doc[
|
346
|
+
doc[rule.content_key]
|
347
347
|
elsif doc.key_exist?(rule.namespaced_name(options[:default_namespace]))
|
348
348
|
doc.fetch(rule.namespaced_name(options[:default_namespace]))
|
349
349
|
else
|
@@ -399,12 +399,12 @@ module Lutaml
|
|
399
399
|
|
400
400
|
value = if value.is_a?(Array)
|
401
401
|
value.map do |v|
|
402
|
-
text_hash?(attr, v) ? v
|
402
|
+
text_hash?(attr, v) ? v.text : v
|
403
403
|
end
|
404
404
|
elsif attr&.raw? && value
|
405
405
|
value.node.children.map(&:to_xml).join
|
406
406
|
elsif text_hash?(attr, value)
|
407
|
-
value
|
407
|
+
value.text
|
408
408
|
else
|
409
409
|
value
|
410
410
|
end
|
@@ -428,7 +428,7 @@ module Lutaml
|
|
428
428
|
|
429
429
|
def text_hash?(attr, value)
|
430
430
|
return false unless value.is_a?(Hash)
|
431
|
-
return value.
|
431
|
+
return value.one? && value.text? unless attr
|
432
432
|
|
433
433
|
!(attr.type <= Serialize) && attr.type != Lutaml::Model::Type::Hash
|
434
434
|
end
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -51,7 +51,9 @@ module Lutaml
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def add_text(element, text)
|
54
|
+
def add_text(element, text, cdata: false)
|
55
|
+
return add_cdata(element, text) if cdata
|
56
|
+
|
55
57
|
if element.is_a?(self.class)
|
56
58
|
element = element.xml.parent
|
57
59
|
end
|
@@ -60,6 +62,10 @@ module Lutaml
|
|
60
62
|
element.add_child(text_node)
|
61
63
|
end
|
62
64
|
|
65
|
+
def add_cdata(element, value)
|
66
|
+
element.cdata(value)
|
67
|
+
end
|
68
|
+
|
63
69
|
def add_namespace_prefix(prefix)
|
64
70
|
xml[prefix] if prefix
|
65
71
|
|
@@ -66,10 +66,16 @@ module Lutaml
|
|
66
66
|
xml.text(text)
|
67
67
|
end
|
68
68
|
|
69
|
-
def add_text(element, text)
|
69
|
+
def add_text(element, text, cdata: false)
|
70
|
+
return element.cdata(text) if cdata
|
71
|
+
|
70
72
|
element << text
|
71
73
|
end
|
72
74
|
|
75
|
+
def add_cdata(element, value)
|
76
|
+
element.cdata(value)
|
77
|
+
end
|
78
|
+
|
73
79
|
# Add XML namespace to document
|
74
80
|
#
|
75
81
|
# Ox doesn't support XML namespaces so we only save the
|
@@ -13,7 +13,15 @@ module Lutaml
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def to_xml(options = {})
|
16
|
-
|
16
|
+
builder_options = {}
|
17
|
+
|
18
|
+
if options.key?(:encoding)
|
19
|
+
builder_options[:encoding] = options[:encoding] unless options[:encoding].nil?
|
20
|
+
else
|
21
|
+
builder_options[:encoding] = "UTF-8"
|
22
|
+
end
|
23
|
+
|
24
|
+
builder = Builder::Nokogiri.build(builder_options) do |xml|
|
17
25
|
if root.is_a?(Lutaml::Model::XmlAdapter::NokogiriElement)
|
18
26
|
root.build_xml(xml)
|
19
27
|
else
|
@@ -35,12 +43,11 @@ module Lutaml
|
|
35
43
|
|
36
44
|
def prefix_xml(xml, mapping, options)
|
37
45
|
if options.key?(:namespace_prefix)
|
38
|
-
options[:namespace_prefix]
|
46
|
+
xml[options[:namespace_prefix]] if options[:namespace_prefix]
|
39
47
|
elsif mapping.namespace_prefix
|
40
48
|
xml[mapping.namespace_prefix]
|
41
|
-
else
|
42
|
-
xml
|
43
49
|
end
|
50
|
+
xml
|
44
51
|
end
|
45
52
|
|
46
53
|
def build_ordered_element(xml, element, options = {})
|
@@ -74,10 +81,12 @@ module Lutaml
|
|
74
81
|
value = attribute_value_for(element, element_rule)
|
75
82
|
|
76
83
|
if element_rule == xml_mapping.content_mapping
|
84
|
+
next if element_rule.cdata && name == "text"
|
85
|
+
|
77
86
|
text = xml_mapping.content_mapping.serialize(element)
|
78
87
|
text = text[curr_index] if text.is_a?(Array)
|
79
88
|
|
80
|
-
next prefixed_xml.
|
89
|
+
next prefixed_xml.add_text(xml, text, cdata: element_rule.cdata) if element.mixed?
|
81
90
|
|
82
91
|
content << text
|
83
92
|
elsif !value.nil? || element_rule.render_nil?
|
@@ -14,8 +14,15 @@ module Lutaml
|
|
14
14
|
|
15
15
|
def to_xml(options = {})
|
16
16
|
builder = Builder::Ox.build
|
17
|
-
|
17
|
+
builder_options = { version: options[:version] }
|
18
18
|
|
19
|
+
if options.key?(:encoding)
|
20
|
+
builder_options[:encoding] = options[:encoding] unless options[:encoding].nil?
|
21
|
+
else
|
22
|
+
builder_options[:encoding] = "UTF-8"
|
23
|
+
end
|
24
|
+
|
25
|
+
builder.xml.instruct(:xml, builder_options)
|
19
26
|
if @root.is_a?(Lutaml::Model::XmlAdapter::OxElement)
|
20
27
|
@root.build_xml(builder)
|
21
28
|
elsif ordered?(@root, options)
|
@@ -56,15 +63,15 @@ module Lutaml
|
|
56
63
|
mapper_class: mapper_class)
|
57
64
|
value = attribute_value_for(element, element_rule)
|
58
65
|
|
66
|
+
next if element_rule == xml_mapping.content_mapping && element_rule.cdata && name == "text"
|
67
|
+
|
59
68
|
if element_rule == xml_mapping.content_mapping
|
60
69
|
text = element.send(xml_mapping.content_mapping.to)
|
61
70
|
text = text[curr_index] if text.is_a?(Array)
|
62
71
|
|
63
|
-
if element.mixed?
|
64
|
-
|
65
|
-
|
66
|
-
content << text
|
67
|
-
end
|
72
|
+
next el.add_text(el, text, cdata: element_rule.cdata) if element.mixed?
|
73
|
+
|
74
|
+
content << text
|
68
75
|
elsif !value.nil? || element_rule.render_nil?
|
69
76
|
value = value[curr_index] if attribute_def.collection?
|
70
77
|
|
@@ -88,10 +95,13 @@ module Lutaml
|
|
88
95
|
|
89
96
|
class OxElement < XmlElement
|
90
97
|
def initialize(node, root_node: nil)
|
91
|
-
|
98
|
+
case node
|
99
|
+
when String
|
92
100
|
super("text", {}, [], node, parent_document: root_node)
|
93
|
-
|
101
|
+
when Ox::Comment
|
94
102
|
super("comment", {}, [], node.value, parent_document: root_node)
|
103
|
+
when Ox::CData
|
104
|
+
super("#cdata-section", {}, [], node.value, parent_document: root_node)
|
95
105
|
else
|
96
106
|
namespace_attributes(node.attributes).each do |(name, value)|
|
97
107
|
if root_node
|
@@ -66,7 +66,7 @@ module Lutaml
|
|
66
66
|
options[:tag_name] = rule.name
|
67
67
|
|
68
68
|
options[:mapper_class] = attribute&.type if attribute
|
69
|
-
options[:
|
69
|
+
options[:set_namespace] = set_namespace?(rule)
|
70
70
|
|
71
71
|
options
|
72
72
|
end
|
@@ -152,16 +152,16 @@ module Lutaml
|
|
152
152
|
)
|
153
153
|
elsif rule.prefix_set?
|
154
154
|
xml.create_and_add_element(rule.name, prefix: prefix) do
|
155
|
-
add_value(xml, value, attribute)
|
155
|
+
add_value(xml, value, attribute, cdata: rule.cdata)
|
156
156
|
end
|
157
157
|
else
|
158
158
|
xml.create_and_add_element(rule.name) do
|
159
|
-
add_value(xml, value, attribute)
|
159
|
+
add_value(xml, value, attribute, cdata: rule.cdata)
|
160
160
|
end
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
|
-
def add_value(xml, value, attribute)
|
164
|
+
def add_value(xml, value, attribute, cdata: false)
|
165
165
|
if !value.nil?
|
166
166
|
serialized_value = attribute.type.serialize(value)
|
167
167
|
|
@@ -172,7 +172,7 @@ module Lutaml
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
else
|
175
|
-
xml.add_text(xml, serialized_value)
|
175
|
+
xml.add_text(xml, serialized_value, cdata: cdata)
|
176
176
|
end
|
177
177
|
end
|
178
178
|
end
|
@@ -185,6 +185,7 @@ module Lutaml
|
|
185
185
|
attributes = options[:xml_attributes] ||= {}
|
186
186
|
attributes = build_attributes(element,
|
187
187
|
xml_mapping, options).merge(attributes)&.compact
|
188
|
+
|
188
189
|
if element.respond_to?(:schema_location) && element.schema_location
|
189
190
|
attributes.merge!(element.schema_location.to_xml_attributes)
|
190
191
|
end
|
@@ -244,7 +245,7 @@ module Lutaml
|
|
244
245
|
value = attribute_value_for(element, rule)
|
245
246
|
return unless render_element?(rule, element, value)
|
246
247
|
|
247
|
-
xml.add_text(xml, value)
|
248
|
+
xml.add_text(xml, value, cdata: rule.cdata)
|
248
249
|
end
|
249
250
|
|
250
251
|
def process_content_mapping(element, content_rule, xml)
|
@@ -261,7 +262,7 @@ module Lutaml
|
|
261
262
|
text = content_rule.serialize(element)
|
262
263
|
text = text.join if text.is_a?(Array)
|
263
264
|
|
264
|
-
xml.add_text(xml, text)
|
265
|
+
xml.add_text(xml, text, cdata: content_rule.cdata)
|
265
266
|
end
|
266
267
|
end
|
267
268
|
|
@@ -275,7 +276,7 @@ module Lutaml
|
|
275
276
|
end
|
276
277
|
|
277
278
|
def set_namespace?(rule)
|
278
|
-
rule.nil? || !rule.namespace_set?
|
279
|
+
rule.nil? || !rule.namespace_set?
|
279
280
|
end
|
280
281
|
|
281
282
|
def render_element?(rule, element, value)
|
@@ -336,7 +337,7 @@ module Lutaml
|
|
336
337
|
end
|
337
338
|
|
338
339
|
def build_attributes(element, xml_mapping, options = {})
|
339
|
-
attrs = if options.fetch(:
|
340
|
+
attrs = if options.fetch(:set_namespace, true)
|
340
341
|
namespace_attributes(xml_mapping)
|
341
342
|
else
|
342
343
|
{}
|