lutaml-model 0.3.0 → 0.3.2
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.yml +0 -5
- data/.rubocop_todo.yml +20 -101
- data/Gemfile +3 -18
- data/README.adoc +1100 -140
- data/lib/lutaml/model/attribute.rb +15 -2
- data/lib/lutaml/model/config.rb +0 -1
- data/lib/lutaml/model/error/invalid_value_error.rb +18 -0
- data/lib/lutaml/model/error.rb +8 -0
- data/lib/lutaml/model/json_adapter/json_document.rb +20 -0
- data/lib/lutaml/model/json_adapter/json_object.rb +28 -0
- data/lib/lutaml/model/json_adapter/{multi_json.rb → multi_json_adapter.rb} +2 -3
- data/lib/lutaml/model/json_adapter/{standard.rb → standard_json_adapter.rb} +2 -3
- data/lib/lutaml/model/json_adapter.rb +1 -31
- data/lib/lutaml/model/key_value_mapping.rb +9 -2
- data/lib/lutaml/model/key_value_mapping_rule.rb +0 -1
- data/lib/lutaml/model/mapping_hash.rb +0 -2
- data/lib/lutaml/model/mapping_rule.rb +5 -3
- data/lib/lutaml/model/schema/json_schema.rb +0 -1
- data/lib/lutaml/model/schema/relaxng_schema.rb +0 -1
- data/lib/lutaml/model/schema/xsd_schema.rb +0 -1
- data/lib/lutaml/model/schema/yaml_schema.rb +0 -1
- data/lib/lutaml/model/schema.rb +0 -1
- data/lib/lutaml/model/serializable.rb +0 -1
- data/lib/lutaml/model/serialize.rb +241 -153
- data/lib/lutaml/model/toml_adapter/toml_document.rb +20 -0
- data/lib/lutaml/model/toml_adapter/toml_object.rb +28 -0
- data/lib/lutaml/model/toml_adapter/toml_rb_adapter.rb +4 -5
- data/lib/lutaml/model/toml_adapter/tomlib_adapter.rb +2 -3
- data/lib/lutaml/model/toml_adapter.rb +0 -31
- data/lib/lutaml/model/type/date_time.rb +20 -0
- data/lib/lutaml/model/type/json.rb +34 -0
- data/lib/lutaml/model/type/time_without_date.rb +4 -3
- data/lib/lutaml/model/type.rb +61 -124
- data/lib/lutaml/model/version.rb +1 -1
- data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +20 -13
- data/lib/lutaml/model/xml_adapter/oga_adapter.rb +4 -5
- data/lib/lutaml/model/xml_adapter/ox_adapter.rb +24 -17
- data/lib/lutaml/model/xml_adapter/xml_attribute.rb +27 -0
- data/lib/lutaml/model/xml_adapter/xml_document.rb +184 -0
- data/lib/lutaml/model/xml_adapter/xml_element.rb +94 -0
- data/lib/lutaml/model/xml_adapter/xml_namespace.rb +49 -0
- data/lib/lutaml/model/xml_adapter.rb +0 -266
- data/lib/lutaml/model/xml_mapping.rb +1 -1
- data/lib/lutaml/model/xml_mapping_rule.rb +3 -4
- data/lib/lutaml/model/yaml_adapter/standard_yaml_adapter.rb +34 -0
- data/lib/lutaml/model/yaml_adapter/yaml_document.rb +20 -0
- data/lib/lutaml/model/yaml_adapter/yaml_object.rb +28 -0
- data/lib/lutaml/model/yaml_adapter.rb +1 -19
- data/lib/lutaml/model.rb +7 -5
- metadata +19 -5
- data/lib/lutaml/model/xml_namespace.rb +0 -47
data/lib/lutaml/model/type.rb
CHANGED
@@ -1,170 +1,97 @@
|
|
1
|
-
# lib/lutaml/model/type.rb
|
2
1
|
require "date"
|
3
2
|
require "bigdecimal"
|
4
3
|
require "securerandom"
|
5
4
|
require "uri"
|
6
5
|
require "ipaddr"
|
7
|
-
require "json"
|
8
6
|
|
9
7
|
module Lutaml
|
10
8
|
module Model
|
11
9
|
module Type
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
10
|
+
# This module provides a set of methods to cast and serialize values
|
11
|
+
|
12
|
+
# TODO: Make Boolean a separate class
|
13
|
+
|
14
|
+
%w(
|
15
|
+
String
|
16
|
+
Integer
|
17
|
+
Float
|
18
|
+
Date
|
19
|
+
Time
|
20
|
+
Boolean
|
21
|
+
Decimal
|
22
|
+
Hash
|
23
|
+
Uuid
|
24
|
+
Symbol
|
25
|
+
Binary
|
26
|
+
Url
|
27
|
+
IpAddress
|
28
|
+
Json
|
29
|
+
).each do |t|
|
29
30
|
class_eval <<~HEREDOC, __FILE__, __LINE__ + 1
|
30
|
-
|
31
|
+
class #{t} # class Integer
|
31
32
|
def self.cast(value) # def self.cast(value)
|
32
33
|
return if value.nil? # return if value.nil?
|
33
|
-
|
34
34
|
Type.cast(value, #{t}) # Type.cast(value, Integer)
|
35
35
|
end # end
|
36
36
|
|
37
37
|
def self.serialize(value) # def self.serialize(value)
|
38
38
|
return if value.nil? # return if value.nil?
|
39
|
-
|
40
39
|
Type.serialize(value, #{t}) # Type.serialize(value, Integer)
|
41
40
|
end # end
|
42
41
|
end # end
|
43
42
|
HEREDOC
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
return if value.nil?
|
49
|
-
|
50
|
-
::Time.parse(value.to_s)
|
51
|
-
# .strftime("%H:%M:%S")
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.serialize(value)
|
55
|
-
value.strftime("%H:%M:%S")
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
class DateTime
|
60
|
-
def self.cast(value)
|
61
|
-
return if value.nil?
|
62
|
-
|
63
|
-
::DateTime.parse(value.to_s).new_offset(0)
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.serialize(value)
|
67
|
-
value.iso8601
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
45
|
+
# TODO: Remove this. The XSD code depends on this but actually should
|
46
|
+
# be converted into a collection, not a specific Array type.
|
71
47
|
class Array
|
72
48
|
def initialize(array)
|
73
49
|
Array(array)
|
74
50
|
end
|
75
51
|
end
|
76
52
|
|
77
|
-
class TextWithTags
|
78
|
-
attr_reader :content
|
79
|
-
|
80
|
-
def initialize(ordered_text_with_tags)
|
81
|
-
@content = ordered_text_with_tags
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.cast(value)
|
85
|
-
return value if value.is_a?(self)
|
86
|
-
|
87
|
-
new(value)
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.serialize(value)
|
91
|
-
value.content.join
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class JSON
|
96
|
-
attr_reader :value
|
97
|
-
|
98
|
-
def initialize(value)
|
99
|
-
@value = value
|
100
|
-
end
|
101
|
-
|
102
|
-
def to_json(*_args)
|
103
|
-
@value.to_json
|
104
|
-
end
|
105
|
-
|
106
|
-
def ==(other)
|
107
|
-
@value == if other.is_a?(::Hash)
|
108
|
-
other
|
109
|
-
else
|
110
|
-
other.value
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.cast(value)
|
115
|
-
return value if value.is_a?(self) || value.nil?
|
116
|
-
|
117
|
-
new(::JSON.parse(value))
|
118
|
-
end
|
119
|
-
|
120
|
-
def self.serialize(value)
|
121
|
-
value.to_json
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
53
|
UUID_REGEX = /\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z/
|
126
54
|
|
127
55
|
def self.cast(value, type)
|
128
56
|
return if value.nil?
|
129
57
|
|
130
|
-
|
58
|
+
case type.to_s.split("::").last
|
59
|
+
when "String"
|
131
60
|
value.to_s
|
132
|
-
|
61
|
+
when "Integer"
|
133
62
|
value.to_i
|
134
|
-
|
63
|
+
when "Float"
|
135
64
|
value.to_f
|
136
|
-
|
65
|
+
when "Date"
|
137
66
|
begin
|
138
67
|
::Date.parse(value.to_s)
|
139
68
|
rescue ArgumentError
|
140
69
|
nil
|
141
70
|
end
|
142
|
-
|
71
|
+
when "DateTime"
|
143
72
|
DateTime.cast(value)
|
144
|
-
|
73
|
+
when "Time"
|
145
74
|
::Time.parse(value.to_s)
|
146
|
-
|
75
|
+
when "TimeWithoutDate"
|
147
76
|
TimeWithoutDate.cast(value)
|
148
|
-
|
77
|
+
when "Boolean"
|
149
78
|
to_boolean(value)
|
150
|
-
|
79
|
+
when "Decimal"
|
151
80
|
BigDecimal(value.to_s)
|
152
|
-
|
81
|
+
when "Hash"
|
153
82
|
normalize_hash(Hash(value))
|
154
|
-
|
83
|
+
when "Uuid"
|
155
84
|
UUID_REGEX.match?(value) ? value : SecureRandom.uuid
|
156
|
-
|
85
|
+
when "Symbol"
|
157
86
|
value.to_sym
|
158
|
-
|
87
|
+
when "Binary"
|
159
88
|
value.force_encoding("BINARY")
|
160
|
-
|
89
|
+
when "Url"
|
161
90
|
URI.parse(value.to_s)
|
162
|
-
|
91
|
+
when "IpAddress"
|
163
92
|
IPAddr.new(value.to_s)
|
164
|
-
|
165
|
-
|
166
|
-
# elsif type == Enum
|
167
|
-
# value
|
93
|
+
when "Json"
|
94
|
+
Json.cast(value)
|
168
95
|
else
|
169
96
|
value
|
170
97
|
end
|
@@ -173,21 +100,22 @@ module Lutaml
|
|
173
100
|
def self.serialize(value, type)
|
174
101
|
return if value.nil?
|
175
102
|
|
176
|
-
|
103
|
+
case type.to_s.split("::").last
|
104
|
+
when "Date"
|
177
105
|
value.iso8601
|
178
|
-
|
106
|
+
when "DateTime"
|
179
107
|
DateTime.serialize(value)
|
180
|
-
|
108
|
+
when "Integer"
|
181
109
|
value.to_i
|
182
|
-
|
110
|
+
when "Float"
|
183
111
|
value.to_f
|
184
|
-
|
112
|
+
when "Boolean"
|
185
113
|
to_boolean(value)
|
186
|
-
|
114
|
+
when "Decimal"
|
187
115
|
value.to_s("F")
|
188
|
-
|
116
|
+
when "Hash"
|
189
117
|
Hash(value)
|
190
|
-
|
118
|
+
when "Json"
|
191
119
|
value.to_json
|
192
120
|
else
|
193
121
|
value.to_s
|
@@ -195,8 +123,13 @@ module Lutaml
|
|
195
123
|
end
|
196
124
|
|
197
125
|
def self.to_boolean(value)
|
198
|
-
|
199
|
-
|
126
|
+
if value == true || value.to_s =~ (/^(true|t|yes|y|1)$/i)
|
127
|
+
return true
|
128
|
+
end
|
129
|
+
|
130
|
+
if value == false || value.nil? || value.to_s =~ (/^(false|f|no|n|0)$/i)
|
131
|
+
return false
|
132
|
+
end
|
200
133
|
|
201
134
|
raise ArgumentError.new("invalid value for Boolean: \"#{value}\"")
|
202
135
|
end
|
@@ -217,3 +150,7 @@ module Lutaml
|
|
217
150
|
end
|
218
151
|
end
|
219
152
|
end
|
153
|
+
|
154
|
+
require_relative "type/time_without_date"
|
155
|
+
require_relative "type/date_time"
|
156
|
+
require_relative "type/json"
|
data/lib/lutaml/model/version.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
# lib/lutaml/model/xml_adapter/nokogiri_adapter.rb
|
2
1
|
require "nokogiri"
|
3
|
-
require_relative "
|
2
|
+
require_relative "xml_document"
|
4
3
|
|
5
4
|
module Lutaml
|
6
5
|
module Model
|
7
6
|
module XmlAdapter
|
8
|
-
class
|
7
|
+
class NokogiriAdapter < XmlDocument
|
9
8
|
def self.parse(xml)
|
10
9
|
parsed = Nokogiri::XML(xml)
|
11
10
|
root = NokogiriElement.new(parsed.root)
|
@@ -13,11 +12,12 @@ module Lutaml
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def to_xml(options = {})
|
16
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
15
|
+
builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
|
17
16
|
if root.is_a?(Lutaml::Model::XmlAdapter::NokogiriElement)
|
18
17
|
root.to_xml(xml)
|
19
18
|
else
|
20
|
-
options[:
|
19
|
+
mapper_class = options[:mapper_class] || @root.class
|
20
|
+
options[:xml_attributes] = build_namespace_attributes(mapper_class)
|
21
21
|
build_element(xml, @root, options)
|
22
22
|
end
|
23
23
|
end
|
@@ -32,7 +32,8 @@ module Lutaml
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def build_unordered_element(xml, element, options = {})
|
35
|
-
|
35
|
+
mapper_class = options[:mapper_class] || element.class
|
36
|
+
xml_mapping = mapper_class.mappings_for(:xml)
|
36
37
|
return xml unless xml_mapping
|
37
38
|
|
38
39
|
attributes = options[:xml_attributes] ||= {}
|
@@ -53,7 +54,7 @@ module Lutaml
|
|
53
54
|
end
|
54
55
|
|
55
56
|
xml_mapping.elements.each do |element_rule|
|
56
|
-
attribute_def = attribute_definition_for(element, element_rule)
|
57
|
+
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
57
58
|
value = attribute_value_for(element, element_rule)
|
58
59
|
|
59
60
|
next if value.nil? && !element_rule.render_nil?
|
@@ -79,7 +80,8 @@ module Lutaml
|
|
79
80
|
end
|
80
81
|
|
81
82
|
def build_ordered_element(xml, element, options = {})
|
82
|
-
|
83
|
+
mapper_class = options[:mapper_class] || element.class
|
84
|
+
xml_mapping = mapper_class.mappings_for(:xml)
|
83
85
|
return xml unless xml_mapping
|
84
86
|
|
85
87
|
attributes = build_attributes(element, xml_mapping)&.compact
|
@@ -106,7 +108,7 @@ module Lutaml
|
|
106
108
|
element_rule = xml_mapping.find_by_name(name)
|
107
109
|
next if element_rule.nil?
|
108
110
|
|
109
|
-
attribute_def = attribute_definition_for(element, element_rule)
|
111
|
+
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
110
112
|
value = attribute_value_for(element, element_rule)
|
111
113
|
nsp_xml = element_rule.prefix ? xml[element_rule.prefix] : xml
|
112
114
|
|
@@ -127,7 +129,12 @@ module Lutaml
|
|
127
129
|
|
128
130
|
def add_to_xml(xml, value, attribute, rule)
|
129
131
|
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
130
|
-
handle_nested_elements(
|
132
|
+
handle_nested_elements(
|
133
|
+
xml,
|
134
|
+
value,
|
135
|
+
rule: rule,
|
136
|
+
attribute: attribute,
|
137
|
+
)
|
131
138
|
else
|
132
139
|
xml.public_send(rule.name) do
|
133
140
|
if !value.nil?
|
@@ -146,11 +153,11 @@ module Lutaml
|
|
146
153
|
end
|
147
154
|
end
|
148
155
|
|
149
|
-
class NokogiriElement <
|
156
|
+
class NokogiriElement < XmlElement
|
150
157
|
def initialize(node, root_node: nil)
|
151
158
|
if root_node
|
152
159
|
node.namespaces.each do |prefix, name|
|
153
|
-
namespace =
|
160
|
+
namespace = XmlNamespace.new(name, prefix)
|
154
161
|
|
155
162
|
root_node.add_namespace(namespace)
|
156
163
|
end
|
@@ -164,7 +171,7 @@ module Lutaml
|
|
164
171
|
attr.name
|
165
172
|
end
|
166
173
|
|
167
|
-
attributes[name] =
|
174
|
+
attributes[name] = XmlAttribute.new(
|
168
175
|
name,
|
169
176
|
attr.value,
|
170
177
|
namespace: attr.namespace&.href,
|
@@ -1,11 +1,10 @@
|
|
1
|
-
# lib/lutaml/model/xml_adapter/oga_adapter.rb
|
2
1
|
require "oga"
|
3
|
-
require_relative "
|
2
|
+
require_relative "xml_document"
|
4
3
|
|
5
4
|
module Lutaml
|
6
5
|
module Model
|
7
6
|
module XmlAdapter
|
8
|
-
class
|
7
|
+
class OgaAdapter < XmlDocument
|
9
8
|
def self.parse(xml)
|
10
9
|
parsed = Oga.parse_xml(xml)
|
11
10
|
root = OgaElement.new(parsed)
|
@@ -51,10 +50,10 @@ module Lutaml
|
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
54
|
-
class OgaElement <
|
53
|
+
class OgaElement < XmlElement
|
55
54
|
def initialize(node)
|
56
55
|
attributes = node.attributes.each_with_object({}) do |attr, hash|
|
57
|
-
hash[attr.name] =
|
56
|
+
hash[attr.name] = XmlAttribute.new(attr.name, attr.value)
|
58
57
|
end
|
59
58
|
super(node.name, attributes, parse_children(node), node.text)
|
60
59
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
# lib/lutaml/model/xml_adapter/ox_adapter.rb
|
2
1
|
require "ox"
|
3
|
-
require_relative "
|
2
|
+
require_relative "xml_document"
|
4
3
|
|
5
4
|
module Lutaml
|
6
5
|
module Model
|
7
6
|
module XmlAdapter
|
8
|
-
class
|
7
|
+
class OxAdapter < XmlDocument
|
9
8
|
def self.parse(xml)
|
10
9
|
parsed = Ox.parse(xml)
|
11
10
|
root = OxElement.new(parsed)
|
@@ -14,9 +13,10 @@ module Lutaml
|
|
14
13
|
|
15
14
|
def to_xml(options = {})
|
16
15
|
builder = Ox::Builder.new
|
16
|
+
|
17
17
|
if @root.is_a?(Lutaml::Model::XmlAdapter::OxElement)
|
18
18
|
@root.to_xml(builder)
|
19
|
-
elsif @root
|
19
|
+
elsif ordered?(@root, options)
|
20
20
|
build_ordered_element(builder, @root, options)
|
21
21
|
else
|
22
22
|
build_element(builder, @root, options)
|
@@ -30,7 +30,8 @@ module Lutaml
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def build_unordered_element(builder, element, options = {})
|
33
|
-
|
33
|
+
mapper_class = options[:mapper_class] || element.class
|
34
|
+
xml_mapping = mapper_class.mappings_for(:xml)
|
34
35
|
return xml unless xml_mapping
|
35
36
|
|
36
37
|
attributes = build_attributes(element, xml_mapping).compact
|
@@ -45,7 +46,7 @@ module Lutaml
|
|
45
46
|
|
46
47
|
builder.element(prefixed_name, attributes) do |el|
|
47
48
|
xml_mapping.elements.each do |element_rule|
|
48
|
-
attribute_def = attribute_definition_for(element, element_rule)
|
49
|
+
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
49
50
|
value = attribute_value_for(element, element_rule)
|
50
51
|
|
51
52
|
val = if attribute_def.collection?
|
@@ -58,7 +59,7 @@ module Lutaml
|
|
58
59
|
|
59
60
|
val.each do |v|
|
60
61
|
if attribute_def&.type&.<= Lutaml::Model::Serialize
|
61
|
-
handle_nested_elements(el, v, element_rule)
|
62
|
+
handle_nested_elements(el, v, rule: element_rule, attribute: attribute_def)
|
62
63
|
else
|
63
64
|
builder.element(element_rule.prefixed_name) do |el|
|
64
65
|
el.text(attribute_def.type.serialize(v)) if v
|
@@ -76,8 +77,9 @@ module Lutaml
|
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
79
|
-
def build_ordered_element(builder, element,
|
80
|
-
|
80
|
+
def build_ordered_element(builder, element, options = {})
|
81
|
+
mapper_class = options[:mapper_class] || element.class
|
82
|
+
xml_mapping = mapper_class.mappings_for(:xml)
|
81
83
|
return xml unless xml_mapping
|
82
84
|
|
83
85
|
attributes = build_attributes(element, xml_mapping).compact
|
@@ -91,7 +93,7 @@ module Lutaml
|
|
91
93
|
|
92
94
|
element_rule = xml_mapping.find_by_name(name)
|
93
95
|
|
94
|
-
attribute_def = attribute_definition_for(element, element_rule)
|
96
|
+
attribute_def = attribute_definition_for(element, element_rule, mapper_class: mapper_class)
|
95
97
|
value = attribute_value_for(element, element_rule)
|
96
98
|
|
97
99
|
if element_rule == xml_mapping.content_mapping
|
@@ -110,7 +112,12 @@ module Lutaml
|
|
110
112
|
|
111
113
|
def add_to_xml(xml, value, attribute, rule)
|
112
114
|
if value && (attribute&.type&.<= Lutaml::Model::Serialize)
|
113
|
-
handle_nested_elements(
|
115
|
+
handle_nested_elements(
|
116
|
+
xml,
|
117
|
+
value,
|
118
|
+
rule: rule,
|
119
|
+
attribute: attribute,
|
120
|
+
)
|
114
121
|
else
|
115
122
|
xml.element(rule.name) do |el|
|
116
123
|
if !value.nil?
|
@@ -129,16 +136,16 @@ module Lutaml
|
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
132
|
-
class OxElement <
|
139
|
+
class OxElement < XmlElement
|
133
140
|
def initialize(node, root_node: nil)
|
134
141
|
if node.is_a?(String)
|
135
142
|
super("text", {}, [], node, parent_document: root_node)
|
136
143
|
else
|
137
144
|
namespace_attributes(node.attributes).each do |(name, value)|
|
138
145
|
if root_node
|
139
|
-
root_node.add_namespace(
|
146
|
+
root_node.add_namespace(XmlNamespace.new(value, name))
|
140
147
|
else
|
141
|
-
add_namespace(
|
148
|
+
add_namespace(XmlNamespace.new(value, name))
|
142
149
|
end
|
143
150
|
end
|
144
151
|
|
@@ -148,11 +155,11 @@ module Lutaml
|
|
148
155
|
namespace_prefix = name.to_s.split(":").first
|
149
156
|
if (n = name.to_s.split(":")).length > 1
|
150
157
|
namespace = (root_node || self).namespaces[namespace_prefix]&.uri
|
151
|
-
namespace ||=
|
158
|
+
namespace ||= XML_NAMESPACE_URI
|
152
159
|
prefix = n.first
|
153
160
|
end
|
154
161
|
|
155
|
-
hash[name.to_s] =
|
162
|
+
hash[name.to_s] = XmlAttribute.new(
|
156
163
|
name.to_s,
|
157
164
|
value,
|
158
165
|
namespace: namespace,
|
@@ -165,7 +172,7 @@ module Lutaml
|
|
165
172
|
attributes,
|
166
173
|
parse_children(node, root_node: root_node || self),
|
167
174
|
node.text,
|
168
|
-
parent_document: root_node
|
175
|
+
parent_document: root_node,
|
169
176
|
)
|
170
177
|
end
|
171
178
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lutaml
|
4
|
+
module Model
|
5
|
+
module XmlAdapter
|
6
|
+
# Represents an XML attribute
|
7
|
+
class XmlAttribute
|
8
|
+
attr_reader :name, :value, :namespace, :namespace_prefix
|
9
|
+
|
10
|
+
def initialize(name, value, namespace: nil, namespace_prefix: nil)
|
11
|
+
@name = name
|
12
|
+
@value = value
|
13
|
+
@namespace = namespace
|
14
|
+
@namespace_prefix = namespace_prefix
|
15
|
+
end
|
16
|
+
|
17
|
+
def unprefixed_name
|
18
|
+
if namespace_prefix
|
19
|
+
name.split(":").last
|
20
|
+
else
|
21
|
+
name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|