lutaml-model 0.3.18 → 0.3.20
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 +7 -8
- data/README.adoc +67 -0
- data/lib/lutaml/model/attribute.rb +16 -6
- data/lib/lutaml/model/serialize.rb +17 -10
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +15 -7
- data/lib/lutaml/model/xml_adapter/xml_document.rb +30 -10
- data/lib/lutaml/model/xml_mapping.rb +48 -1
- data/lib/lutaml/model/xml_mapping_rule.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bab2e14b0b68874c47f728f68e7269e1347ab0997d005f93f16b16e897ba386d
|
4
|
+
data.tar.gz: 31238907ad9f6f969e0a557c85207136b9f49b335494d5d2a2dc6552261b0bab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc788a5dca9293c258488278ac0617fd3658e16f520c75df304e70b5591832a1ae84ae5ee43d091539904e7a66aef0a03801ac21b997f7b2b2f5bdb99d31e7dd
|
7
|
+
data.tar.gz: 31026554dadcf54876140fee95c5a2bc4b847cee45e09022b6c5a018a2ea9ff2fa1f067a515acf7cacb880e470935d3e28b34a773d19aae9723a5542c6a55a8a
|
data/.rubocop_todo.yml
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2024-10-
|
3
|
+
# on 2024-10-30 07:34:33 UTC using RuboCop version 1.66.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 146
|
10
10
|
# This cop supports safe autocorrection (--autocorrect).
|
11
11
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
12
12
|
# URISchemes: http, https
|
@@ -46,7 +46,7 @@ Metrics/AbcSize:
|
|
46
46
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
47
47
|
- 'lib/lutaml/model/xml_mapping_rule.rb'
|
48
48
|
|
49
|
-
# Offense count:
|
49
|
+
# Offense count: 5
|
50
50
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
51
51
|
# AllowedMethods: refine
|
52
52
|
Metrics/BlockLength:
|
@@ -64,12 +64,12 @@ Metrics/CyclomaticComplexity:
|
|
64
64
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
65
65
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
66
66
|
|
67
|
-
# Offense count:
|
67
|
+
# Offense count: 51
|
68
68
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
69
69
|
Metrics/MethodLength:
|
70
|
-
Max:
|
70
|
+
Max: 43
|
71
71
|
|
72
|
-
# Offense count:
|
72
|
+
# Offense count: 7
|
73
73
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
74
74
|
Metrics/ParameterLists:
|
75
75
|
Max: 13
|
@@ -85,12 +85,11 @@ Metrics/PerceivedComplexity:
|
|
85
85
|
- 'lib/lutaml/model/xml_adapter/ox_adapter.rb'
|
86
86
|
- 'lib/lutaml/model/xml_adapter/xml_document.rb'
|
87
87
|
|
88
|
-
# Offense count:
|
88
|
+
# Offense count: 7
|
89
89
|
# Configuration parameters: Prefixes, AllowedPatterns.
|
90
90
|
# Prefixes: when, with, without
|
91
91
|
RSpec/ContextWording:
|
92
92
|
Exclude:
|
93
|
-
- 'spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb'
|
94
93
|
- 'spec/lutaml/model/xml_adapter/oga_adapter_spec.rb'
|
95
94
|
- 'spec/lutaml/model/xml_adapter/ox_adapter_spec.rb'
|
96
95
|
- 'spec/lutaml/model/xml_adapter/xml_namespace_spec.rb'
|
data/README.adoc
CHANGED
@@ -618,6 +618,73 @@ end
|
|
618
618
|
----
|
619
619
|
====
|
620
620
|
|
621
|
+
|
622
|
+
==== Mapping all content (XML only)
|
623
|
+
|
624
|
+
WARNING: This feature is only applicable to XML (for now).
|
625
|
+
|
626
|
+
The `map_all` tag in XML mapping captures and maps all content within an XML
|
627
|
+
element into a single attribute in the target Ruby object.
|
628
|
+
|
629
|
+
The use case for `map_all` is to tell Lutaml::Model to not parse the content of
|
630
|
+
the XML element at all, and instead handle it as an XML string.
|
631
|
+
|
632
|
+
This is useful in the case where the content of an XML element is not to be
|
633
|
+
handled by a Lutaml::Model::Serializable object.
|
634
|
+
|
635
|
+
This feature is commonly used with custom methods or a custom model object to
|
636
|
+
handle the content.
|
637
|
+
|
638
|
+
This includes:
|
639
|
+
|
640
|
+
* nested tags
|
641
|
+
* attributes
|
642
|
+
* text nodes
|
643
|
+
|
644
|
+
The `map_all` tag is **exclusive** and cannot be combined with other mappings
|
645
|
+
(`map_element`, `map_attribute`, `map_content`) for the same element, ensuring
|
646
|
+
it captures the entire inner XML content.
|
647
|
+
|
648
|
+
NOTE: An error is raised if `map_all` is defined alongside any other mapping in
|
649
|
+
the same XML mapping context.
|
650
|
+
|
651
|
+
Syntax:
|
652
|
+
|
653
|
+
[source,ruby]
|
654
|
+
----
|
655
|
+
xml do
|
656
|
+
map_all to: :name_of_attribute
|
657
|
+
end
|
658
|
+
----
|
659
|
+
|
660
|
+
.Mapping all the content using `map_all`
|
661
|
+
[example]
|
662
|
+
====
|
663
|
+
[source,ruby]
|
664
|
+
----
|
665
|
+
class ExampleMapping < Lutaml::Model::Serializable
|
666
|
+
attribute :description, :string
|
667
|
+
|
668
|
+
xml do
|
669
|
+
map_all to: :description
|
670
|
+
end
|
671
|
+
end
|
672
|
+
----
|
673
|
+
|
674
|
+
[source,xml]
|
675
|
+
----
|
676
|
+
<ExampleMapping>Content with <b>tags</b> and <i>formatting</i>.</ExampleMapping>
|
677
|
+
----
|
678
|
+
|
679
|
+
[source,ruby]
|
680
|
+
----
|
681
|
+
> parsed = ExampleMapping.from_xml(xml)
|
682
|
+
> puts parsed.all_content
|
683
|
+
# "Content with <b>tags</b> and <i>formatting</i>."
|
684
|
+
----
|
685
|
+
====
|
686
|
+
|
687
|
+
|
621
688
|
==== Mapping elements
|
622
689
|
|
623
690
|
The `map_element` method maps an XML element to a data model attribute.
|
@@ -13,9 +13,12 @@ module Lutaml
|
|
13
13
|
|
14
14
|
def initialize(name, type, options = {})
|
15
15
|
@name = name
|
16
|
-
|
16
|
+
|
17
|
+
validate_type!(type)
|
18
|
+
@type = cast_type!(type)
|
19
|
+
|
20
|
+
validate_options!(options)
|
17
21
|
@options = options
|
18
|
-
validate_options!
|
19
22
|
|
20
23
|
@raw = !!options[:raw]
|
21
24
|
|
@@ -29,7 +32,7 @@ module Lutaml
|
|
29
32
|
@options[:delegate]
|
30
33
|
end
|
31
34
|
|
32
|
-
def cast_type(type)
|
35
|
+
def cast_type!(type)
|
33
36
|
case type
|
34
37
|
when Class
|
35
38
|
type
|
@@ -212,11 +215,18 @@ module Lutaml
|
|
212
215
|
|
213
216
|
private
|
214
217
|
|
215
|
-
def validate_options!
|
216
|
-
if (
|
217
|
-
raise StandardError, "Invalid options given for `#{name}` #{
|
218
|
+
def validate_options!(options)
|
219
|
+
if (invalid_opts = options.keys - ALLOWED_OPTIONS).any?
|
220
|
+
raise StandardError, "Invalid options given for `#{name}` #{invalid_opts}"
|
218
221
|
end
|
219
222
|
end
|
223
|
+
|
224
|
+
def validate_type!(type)
|
225
|
+
return true if type.is_a?(Class)
|
226
|
+
return true if [Symbol, String].include?(type.class) && cast_type!(type)
|
227
|
+
|
228
|
+
raise ArgumentError, "Invalid type: #{type}, must be a Symbol, String or a Class"
|
229
|
+
end
|
220
230
|
end
|
221
231
|
end
|
222
232
|
end
|
@@ -332,7 +332,9 @@ module Lutaml
|
|
332
332
|
mappings.each do |rule|
|
333
333
|
raise "Attribute '#{rule.to}' not found in #{self}" unless valid_rule?(rule)
|
334
334
|
|
335
|
-
value = if rule.
|
335
|
+
value = if rule.raw_mapping?
|
336
|
+
doc.node.inner_xml
|
337
|
+
elsif rule.content_mapping?
|
336
338
|
doc["text"]
|
337
339
|
elsif doc.key_exist?(rule.namespaced_name)
|
338
340
|
doc.fetch(rule.namespaced_name)
|
@@ -397,16 +399,21 @@ module Lutaml
|
|
397
399
|
value
|
398
400
|
end
|
399
401
|
|
400
|
-
|
401
|
-
value = attr.cast(
|
402
|
-
value,
|
403
|
-
:xml,
|
404
|
-
caller_class: self,
|
405
|
-
mixed_content: rule.mixed_content,
|
406
|
-
)
|
407
|
-
end
|
402
|
+
return value unless cast_value?(attr, rule)
|
408
403
|
|
409
|
-
|
404
|
+
attr.cast(
|
405
|
+
value,
|
406
|
+
:xml,
|
407
|
+
caller_class: self,
|
408
|
+
mixed_content: rule.mixed_content,
|
409
|
+
)
|
410
|
+
end
|
411
|
+
|
412
|
+
def cast_value?(attr, rule)
|
413
|
+
attr &&
|
414
|
+
!rule.raw_mapping? &&
|
415
|
+
!rule.content_mapping? &&
|
416
|
+
!rule.custom_methods[:from]
|
410
417
|
end
|
411
418
|
|
412
419
|
def text_hash?(attr, value)
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -33,6 +33,16 @@ module Lutaml
|
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
def prefix_xml(xml, mapping, options)
|
37
|
+
if options.key?(:namespace_prefix)
|
38
|
+
options[:namespace_prefix] ? xml[options[:namespace_prefix]] : xml
|
39
|
+
elsif mapping.namespace_prefix
|
40
|
+
xml[mapping.namespace_prefix]
|
41
|
+
else
|
42
|
+
xml
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
def build_ordered_element(xml, element, options = {})
|
37
47
|
mapper_class = options[:mapper_class] || element.class
|
38
48
|
xml_mapping = mapper_class.mappings_for(:xml)
|
@@ -40,13 +50,7 @@ module Lutaml
|
|
40
50
|
|
41
51
|
attributes = build_attributes(element, xml_mapping)&.compact
|
42
52
|
|
43
|
-
prefixed_xml =
|
44
|
-
options[:namespace_prefix] ? xml[options[:namespace_prefix]] : xml
|
45
|
-
elsif xml_mapping.namespace_prefix
|
46
|
-
xml[xml_mapping.namespace_prefix]
|
47
|
-
else
|
48
|
-
xml
|
49
|
-
end
|
53
|
+
prefixed_xml = prefix_xml(xml, xml_mapping, options)
|
50
54
|
|
51
55
|
tag_name = options[:tag_name] || xml_mapping.root_element
|
52
56
|
tag_name = "#{tag_name}_" if prefixed_xml.respond_to?(tag_name)
|
@@ -148,6 +152,10 @@ module Lutaml
|
|
148
152
|
build_xml.doc.root.to_xml
|
149
153
|
end
|
150
154
|
|
155
|
+
def inner_xml
|
156
|
+
children.map(&:to_xml).join
|
157
|
+
end
|
158
|
+
|
151
159
|
def build_xml(builder = nil)
|
152
160
|
builder ||= Builder::Nokogiri.build
|
153
161
|
|
@@ -227,16 +227,36 @@ module Lutaml
|
|
227
227
|
)
|
228
228
|
end
|
229
229
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
230
|
+
process_content_mapping(element, xml_mapping.content_mapping, prefixed_xml)
|
231
|
+
|
232
|
+
process_raw_mapping(element, xml_mapping.raw_mapping, prefixed_xml)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def process_raw_mapping(element, rule, xml)
|
237
|
+
return unless rule
|
238
|
+
|
239
|
+
value = attribute_value_for(element, rule)
|
240
|
+
return unless render_element?(rule, element, value)
|
241
|
+
|
242
|
+
xml.add_text(xml, value)
|
243
|
+
end
|
244
|
+
|
245
|
+
def process_content_mapping(element, content_rule, xml)
|
246
|
+
return unless content_rule
|
247
|
+
|
248
|
+
if content_rule.custom_methods[:to]
|
249
|
+
@root.send(
|
250
|
+
content_rule.custom_methods[:to],
|
251
|
+
element,
|
252
|
+
xml.parent,
|
253
|
+
xml,
|
254
|
+
)
|
255
|
+
else
|
256
|
+
text = content_rule.serialize(element)
|
257
|
+
text = text.join if text.is_a?(Array)
|
258
|
+
|
259
|
+
xml.add_text(xml, text)
|
240
260
|
end
|
241
261
|
end
|
242
262
|
|
@@ -13,6 +13,7 @@ module Lutaml
|
|
13
13
|
@elements = {}
|
14
14
|
@attributes = {}
|
15
15
|
@content_mapping = nil
|
16
|
+
@raw_mapping = nil
|
16
17
|
@mixed_content = false
|
17
18
|
end
|
18
19
|
|
@@ -123,7 +124,39 @@ module Lutaml
|
|
123
124
|
)
|
124
125
|
end
|
125
126
|
|
127
|
+
def map_all(
|
128
|
+
to:,
|
129
|
+
render_nil: false,
|
130
|
+
render_default: false,
|
131
|
+
delegate: nil,
|
132
|
+
with: {},
|
133
|
+
namespace: (namespace_set = false
|
134
|
+
nil),
|
135
|
+
prefix: (prefix_set = false
|
136
|
+
nil)
|
137
|
+
)
|
138
|
+
validate!("__raw_mapping", to, with)
|
139
|
+
|
140
|
+
rule = XmlMappingRule.new(
|
141
|
+
"__raw_mapping",
|
142
|
+
to: to,
|
143
|
+
render_nil: render_nil,
|
144
|
+
render_default: render_default,
|
145
|
+
with: with,
|
146
|
+
delegate: delegate,
|
147
|
+
namespace: namespace,
|
148
|
+
prefix: prefix,
|
149
|
+
default_namespace: namespace_uri,
|
150
|
+
namespace_set: namespace_set != false,
|
151
|
+
prefix_set: prefix_set != false,
|
152
|
+
)
|
153
|
+
|
154
|
+
@raw_mapping = rule
|
155
|
+
end
|
156
|
+
|
126
157
|
def validate!(key, to, with)
|
158
|
+
validate_mappings!(key)
|
159
|
+
|
127
160
|
if to.nil? && with.empty?
|
128
161
|
msg = ":to or :with argument is required for mapping '#{key}'"
|
129
162
|
raise IncorrectMappingArgumentsError.new(msg)
|
@@ -135,6 +168,16 @@ module Lutaml
|
|
135
168
|
end
|
136
169
|
end
|
137
170
|
|
171
|
+
def validate_mappings!(key)
|
172
|
+
unless @raw_mapping.nil?
|
173
|
+
raise StandardError, "no other mappings are allowed with map_all"
|
174
|
+
end
|
175
|
+
|
176
|
+
if !mappings.empty? && key == "__raw_mapping"
|
177
|
+
raise StandardError, "map_all is not allowed with other mappings"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
138
181
|
def elements
|
139
182
|
@elements.values
|
140
183
|
end
|
@@ -147,8 +190,12 @@ module Lutaml
|
|
147
190
|
@content_mapping
|
148
191
|
end
|
149
192
|
|
193
|
+
def raw_mapping
|
194
|
+
@raw_mapping
|
195
|
+
end
|
196
|
+
|
150
197
|
def mappings
|
151
|
-
elements + attributes + [content_mapping].compact
|
198
|
+
elements + attributes + [content_mapping, raw_mapping].compact
|
152
199
|
end
|
153
200
|
|
154
201
|
def element(name)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lutaml-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|