rng 0.1.1 → 0.1.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.rubocop_todo.yml +64 -0
  4. data/CODE_OF_CONDUCT.md +132 -0
  5. data/Gemfile +3 -1
  6. data/README.adoc +402 -0
  7. data/lib/rng/any_name.rb +26 -0
  8. data/lib/rng/attribute.rb +58 -4
  9. data/lib/rng/choice.rb +60 -0
  10. data/lib/rng/data.rb +32 -0
  11. data/lib/rng/define.rb +51 -3
  12. data/lib/rng/element.rb +62 -16
  13. data/lib/rng/empty.rb +23 -0
  14. data/lib/rng/except.rb +62 -0
  15. data/lib/rng/external_ref.rb +28 -0
  16. data/lib/rng/grammar.rb +36 -0
  17. data/lib/rng/group.rb +60 -0
  18. data/lib/rng/include.rb +24 -0
  19. data/lib/rng/interleave.rb +58 -0
  20. data/lib/rng/list.rb +56 -0
  21. data/lib/rng/mixed.rb +58 -0
  22. data/lib/rng/name.rb +28 -0
  23. data/lib/rng/not_allowed.rb +23 -0
  24. data/lib/rng/ns_name.rb +31 -0
  25. data/lib/rng/one_or_more.rb +58 -0
  26. data/lib/rng/optional.rb +58 -0
  27. data/lib/rng/param.rb +30 -0
  28. data/lib/rng/parent_ref.rb +28 -0
  29. data/lib/rng/parse_rnc.rb +26 -0
  30. data/lib/rng/pattern.rb +24 -0
  31. data/lib/rng/ref.rb +28 -0
  32. data/lib/rng/rnc_parser.rb +351 -94
  33. data/lib/rng/start.rb +54 -5
  34. data/lib/rng/text.rb +26 -0
  35. data/lib/rng/to_rnc.rb +55 -0
  36. data/lib/rng/value.rb +29 -0
  37. data/lib/rng/version.rb +1 -1
  38. data/lib/rng/zero_or_more.rb +58 -0
  39. data/lib/rng.rb +29 -5
  40. data/rng.gemspec +3 -2
  41. data/spec/fixtures/rnc/address_book.rnc +10 -0
  42. data/spec/fixtures/rnc/complex_example.rnc +61 -0
  43. data/spec/fixtures/rng/address_book.rng +20 -0
  44. data/spec/fixtures/rng/relaxng.rng +335 -0
  45. data/spec/fixtures/rng/testSuite.rng +163 -0
  46. data/spec/fixtures/spectest.xml +6845 -0
  47. data/spec/rng/rnc_parser_spec.rb +6 -4
  48. data/spec/rng/rnc_roundtrip_spec.rb +121 -0
  49. data/spec/rng/schema_spec.rb +115 -166
  50. data/spec/rng/spectest_spec.rb +195 -0
  51. data/spec/spec_helper.rb +33 -0
  52. metadata +54 -7
  53. data/lib/rng/builder.rb +0 -158
  54. data/lib/rng/rng_parser.rb +0 -107
  55. data/lib/rng/schema.rb +0 -18
  56. data/spec/rng/rng_parser_spec.rb +0 -102
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "parslet"
2
- require_relative "schema"
4
+ require "nokogiri"
5
+ require_relative "grammar"
3
6
 
4
7
  module Rng
5
8
  class RncParser < Parslet::Parser
@@ -12,125 +15,379 @@ module Rng
12
15
  rule(:comma?) { (whitespace >> comma >> whitespace).maybe }
13
16
 
14
17
  rule(:identifier) { match("[a-zA-Z0-9_]").repeat(1).as(:identifier) }
18
+ rule(:namespace_prefix) { identifier.as(:prefix) >> str(":") }
19
+ rule(:namespace_prefix?) { namespace_prefix.maybe }
20
+ rule(:qualified_name) { namespace_prefix? >> identifier.as(:local_name) }
21
+
22
+ rule(:datatype_library) { str("datatypes") >> space >> identifier.as(:prefix) >> space >> string_literal.as(:uri) }
15
23
 
16
- rule(:element_def) {
24
+ rule(:string_literal) { str('"') >> match('[^"]').repeat.as(:string) >> str('"') }
25
+
26
+ rule(:element_def) do
17
27
  str("element") >> space >>
18
- identifier >>
19
- whitespace >>
20
- str("{") >>
21
- whitespace >>
22
- content.maybe.as(:content) >>
23
- whitespace >>
24
- str("}") >>
25
- (str("*") | str("+") | str("?")).maybe.as(:occurrence)
26
- }
28
+ qualified_name.as(:name) >>
29
+ whitespace >>
30
+ str("{") >>
31
+ whitespace >>
32
+ content.maybe.as(:content) >>
33
+ whitespace >>
34
+ str("}") >>
35
+ (str("*") | str("+") | str("?")).maybe.as(:occurrence)
36
+ end
27
37
 
28
- rule(:attribute_def) {
38
+ rule(:attribute_def) do
29
39
  str("attribute") >> space >>
30
- identifier.as(:name) >>
31
- whitespace >>
32
- str("{") >>
33
- whitespace >>
34
- (str("text")).as(:type) >>
35
- whitespace >>
36
- str("}")
37
- }
40
+ qualified_name.as(:name) >>
41
+ whitespace >>
42
+ str("{") >>
43
+ whitespace >>
44
+ (datatype_ref | str("text")).as(:type) >>
45
+ whitespace >>
46
+ str("}")
47
+ end
48
+
49
+ rule(:datatype_ref) do
50
+ identifier.as(:prefix) >> str(":") >> identifier.as(:type)
51
+ end
38
52
 
39
53
  rule(:text_def) { str("text").as(:text) }
54
+ rule(:empty_def) { str("empty").as(:empty) }
40
55
 
41
- rule(:content_item) {
42
- ((element_def | attribute_def | text_def).as(:item) >> comma?).repeat(1).as(:items)
43
- }
56
+ rule(:group_def) do
57
+ str("(") >>
58
+ whitespace >>
59
+ content.as(:group) >>
60
+ whitespace >>
61
+ str(")") >>
62
+ (str("*") | str("+") | str("?")).maybe.as(:occurrence)
63
+ end
64
+
65
+ rule(:choice_def) do
66
+ content_item.as(:first) >>
67
+ (whitespace >> str("|") >> whitespace >> content_item.as(:second)).repeat(1).as(:rest)
68
+ end
44
69
 
45
- rule(:content) { content_item }
70
+ rule(:named_pattern) do
71
+ identifier.as(:name) >> whitespace >> str("=") >> whitespace >> content_item.as(:pattern)
72
+ end
46
73
 
47
- rule(:grammar) { whitespace >> element_def.as(:element) >> whitespace }
74
+ rule(:content_item) do
75
+ element_def | attribute_def | text_def | empty_def | group_def | choice_def | identifier.as(:ref)
76
+ end
77
+
78
+ rule(:content) do
79
+ (content_item >> (comma? >> content_item).repeat).as(:items)
80
+ end
81
+
82
+ rule(:start_def) do
83
+ str("start") >> whitespace >> str("=") >> whitespace >> content_item.as(:start)
84
+ end
85
+
86
+ rule(:grammar) do
87
+ whitespace >>
88
+ datatype_library.maybe.as(:datatype_library) >>
89
+ whitespace >>
90
+ (start_def | named_pattern | element_def).as(:root) >>
91
+ (whitespace >> (named_pattern | element_def)).repeat.as(:definitions) >>
92
+ whitespace
93
+ end
48
94
 
49
95
  root(:grammar)
50
96
 
51
- def parse(input)
52
- tree = super(input.strip)
53
- build_schema(tree)
97
+ def self.parse(input)
98
+ parser = new
99
+ tree = parser.parse(input.strip)
100
+ convert_to_rng(tree)
54
101
  end
55
102
 
56
- private
103
+ def self.to_rnc(schema)
104
+ # Convert RNG schema to RNC
105
+ builder = RncBuilder.new
106
+ builder.build(schema)
107
+ end
108
+
109
+ def self.convert_to_rng(tree)
110
+ builder = Nokogiri::XML::Builder.new(encoding: "UTF-8") do |xml|
111
+ if tree[:root].key?(:start)
112
+ # This is a grammar with named patterns
113
+ xml.grammar(xmlns: "http://relaxng.org/ns/structure/1.0") do
114
+ # Add datatype library if present
115
+ xml.datatypeLibrary tree[:datatype_library][:uri][:string].to_s if tree[:datatype_library]
116
+
117
+ # Process start pattern
118
+ xml.start do
119
+ process_content_item(xml, tree[:root][:start])
120
+ end
121
+
122
+ # Process named patterns
123
+ tree[:definitions]&.each do |def_item|
124
+ next unless def_item.key?(:name)
125
+
126
+ xml.define(name: def_item[:name][:identifier].to_s) do
127
+ process_content_item(xml, def_item[:pattern])
128
+ end
129
+ end
130
+ end
131
+ else
132
+ # This is a simple element pattern
133
+ process_content_item(xml, tree[:root])
134
+ end
135
+ end
136
+
137
+ builder.to_xml
138
+ end
139
+
140
+ def self.process_content_item(xml, item)
141
+ if item.key?(:name)
142
+ # Element definition
143
+ attrs = {}
144
+ attrs[:name] = item[:name][:local_name][:identifier].to_s
145
+
146
+ attrs[:ns] = item[:name][:prefix][:identifier].to_s if item[:name][:prefix]
147
+
148
+ xml.element(attrs) do
149
+ if item[:content]
150
+ item[:content][:items].each do |content_item|
151
+ process_content_item(xml, content_item)
152
+ end
153
+ end
154
+ end
155
+
156
+ # Handle occurrence
157
+ if item[:occurrence]
158
+ case item[:occurrence].to_s
159
+ when "*"
160
+ xml.parent.name = "zeroOrMore"
161
+ when "+"
162
+ xml.parent.name = "oneOrMore"
163
+ when "?"
164
+ xml.parent.name = "optional"
165
+ end
166
+ end
167
+ elsif item.key?(:attr_name)
168
+ # Attribute definition
169
+ attrs = {}
170
+ attrs[:name] = item[:attr_name][:local_name][:identifier].to_s
171
+
172
+ attrs[:ns] = item[:attr_name][:prefix][:identifier].to_s if item[:attr_name][:prefix]
173
+
174
+ xml.attribute(attrs) do
175
+ if item[:type] == "text"
176
+ xml.text
177
+ elsif item[:type].key?(:prefix)
178
+ xml.data(type: item[:type][:type][:identifier].to_s,
179
+ datatypeLibrary: "http://www.w3.org/2001/XMLSchema-datatypes")
180
+ end
181
+ end
182
+ elsif item.key?(:text)
183
+ xml.text
184
+ elsif item.key?(:empty)
185
+ xml.empty
186
+ elsif item.key?(:group)
187
+ xml.group do
188
+ item[:group][:items].each do |group_item|
189
+ process_content_item(xml, group_item)
190
+ end
191
+ end
192
+
193
+ # Handle occurrence
194
+ if item[:occurrence]
195
+ case item[:occurrence].to_s
196
+ when "*"
197
+ xml.parent.name = "zeroOrMore"
198
+ when "+"
199
+ xml.parent.name = "oneOrMore"
200
+ when "?"
201
+ xml.parent.name = "optional"
202
+ end
203
+ end
204
+ elsif item.key?(:first) && item.key?(:rest)
205
+ # Choice definition
206
+ xml.choice do
207
+ process_content_item(xml, item[:first])
208
+ item[:rest].each do |choice_item|
209
+ process_content_item(xml, choice_item[:second])
210
+ end
211
+ end
212
+ elsif item.key?(:ref)
213
+ # Reference to a named pattern
214
+ xml.ref(name: item[:ref][:identifier].to_s)
215
+ end
216
+ end
217
+ end
218
+
219
+ class RncBuilder
220
+ def build(schema)
221
+ if schema.element
222
+ # Simple element pattern
223
+ build_element(schema.element)
224
+ else
225
+ # Grammar with named patterns
226
+ result = []
227
+
228
+ # Add datatype library if present
229
+ if schema.datatypeLibrary
230
+ result << "datatypes xsd = \"#{schema.datatypeLibrary}\""
231
+ result << ""
232
+ end
233
+
234
+ # Process start pattern
235
+ if schema.start
236
+ result << "start = #{build_pattern(schema.start)}"
237
+ result << ""
238
+ end
239
+
240
+ # Process named patterns
241
+ if schema.define && !schema.define.empty?
242
+ schema.define.each do |define|
243
+ result << "#{define.name} = #{build_pattern(define)}"
244
+ result << ""
245
+ end
246
+ end
57
247
 
58
- def build_schema(tree)
59
- element = tree[:element]
60
- Schema.new(
61
- start: Start.new(
62
- elements: [build_element(element)],
63
- ),
64
- )
248
+ result.join("\n")
249
+ end
65
250
  end
66
251
 
252
+ private
253
+
67
254
  def build_element(element)
68
- name = element[:identifier].to_s
69
- content = element[:content]&.[](:items)
70
- occurrence = element[:occurrence]
71
-
72
- # Create base element
73
- el = Element.new(
74
- name: name,
75
- attributes: [],
76
- elements: [],
77
- text: false,
78
- )
79
-
80
- if content
81
- current_elements = []
82
- current_attributes = []
83
-
84
- content.each do |item|
85
- case
86
- when item[:item][:name] || (item[:item][:identifier] && item[:item][:type])
87
- attr_name = item[:item][:name] || item[:item][:identifier]
88
- attr = Attribute.new(
89
- name: attr_name.to_s,
90
- type: ["string"],
91
- )
92
- current_attributes << attr
93
- when item[:item][:identifier]
94
- current_elements << build_element(item[:item])
95
- when item[:item][:text]
96
- el.text = true
255
+ result = "element #{element.name} {\n"
256
+ result += " #{build_content(element)}\n"
257
+ result += "}"
258
+ result
259
+ end
260
+
261
+ def build_content(node)
262
+ content_parts = []
263
+
264
+ # Process attributes
265
+ if node.attribute
266
+ if node.attribute.is_a?(Array)
267
+ node.attribute.each do |attr|
268
+ content_parts << build_attribute(attr)
97
269
  end
270
+ else
271
+ content_parts << build_attribute(node.attribute)
98
272
  end
273
+ end
99
274
 
100
- el.attributes = current_attributes
101
- el.elements = current_elements
275
+ # Process child elements
276
+ if node.element
277
+ if node.element.is_a?(Array)
278
+ node.element.each do |elem|
279
+ content_parts << build_element(elem)
280
+ end
281
+ else
282
+ content_parts << build_element(node.element)
283
+ end
102
284
  end
103
285
 
104
- # Handle occurrence modifiers
105
- result = el
106
- case occurrence
107
- when "*"
108
- result = Element.new(
109
- name: el.name,
110
- attributes: el.attributes,
111
- elements: el.elements,
112
- text: el.text,
113
- )
114
- result.zero_or_more = [el]
115
- when "+"
116
- result = Element.new(
117
- name: el.name,
118
- attributes: el.attributes,
119
- elements: el.elements,
120
- text: el.text,
121
- )
122
- result.one_or_more = [el]
123
- when "?"
124
- result = Element.new(
125
- name: el.name,
126
- attributes: el.attributes,
127
- elements: el.elements,
128
- text: el.text,
129
- )
130
- result.optional = [el]
286
+ # Process text
287
+ content_parts << "text" if node.text
288
+
289
+ # Process empty
290
+ content_parts << "empty" if node.empty
291
+
292
+ # Process choice
293
+ if node.choice
294
+ choice_parts = []
295
+ if node.choice.is_a?(Array)
296
+ node.choice.each do |choice|
297
+ choice_parts << build_pattern(choice)
298
+ end
299
+ else
300
+ choice_parts << build_pattern(node.choice)
301
+ end
302
+ content_parts << choice_parts.join(" | ")
303
+ end
304
+
305
+ # Process group
306
+ if node.group
307
+ group_parts = []
308
+ if node.group.is_a?(Array)
309
+ node.group.each do |group|
310
+ group_parts << build_pattern(group)
311
+ end
312
+ else
313
+ group_parts << build_pattern(node.group)
314
+ end
315
+ content_parts << "(#{group_parts.join(", ")})"
131
316
  end
132
317
 
318
+ # Process ref
319
+ if node.ref
320
+ if node.ref.is_a?(Array)
321
+ node.ref.each do |ref|
322
+ content_parts << ref.name
323
+ end
324
+ else
325
+ content_parts << node.ref.name
326
+ end
327
+ end
328
+
329
+ # Process zeroOrMore
330
+ content_parts << "#{build_pattern(node.zeroOrMore)}*" if node.zeroOrMore
331
+
332
+ # Process oneOrMore
333
+ content_parts << "#{build_pattern(node.oneOrMore)}+" if node.oneOrMore
334
+
335
+ # Process optional
336
+ content_parts << "#{build_pattern(node.optional)}?" if node.optional
337
+
338
+ content_parts.join(",\n ")
339
+ end
340
+
341
+ def build_attribute(attr)
342
+ result = "attribute #{attr.name} { "
343
+
344
+ result += if attr.data
345
+ if attr.data.type
346
+ "xsd:#{attr.data.type}"
347
+ else
348
+ "text"
349
+ end
350
+ else
351
+ "text"
352
+ end
353
+
354
+ result += " }"
133
355
  result
134
356
  end
357
+
358
+ def build_pattern(node)
359
+ if node.element
360
+ build_element(node.element)
361
+ elsif node.ref
362
+ node.ref.name
363
+ elsif node.choice
364
+ choice_parts = []
365
+ if node.choice.is_a?(Array)
366
+ node.choice.each do |choice|
367
+ choice_parts << build_pattern(choice)
368
+ end
369
+ else
370
+ choice_parts << build_pattern(node.choice)
371
+ end
372
+ choice_parts.join(" | ")
373
+ elsif node.group
374
+ group_parts = []
375
+ if node.group.is_a?(Array)
376
+ node.group.each do |group|
377
+ group_parts << build_pattern(group)
378
+ end
379
+ else
380
+ group_parts << build_pattern(node.group)
381
+ end
382
+ "(#{group_parts.join(", ")})"
383
+ elsif node.text
384
+ "text"
385
+ elsif node.empty
386
+ "empty"
387
+ else
388
+ # Default case
389
+ ""
390
+ end
391
+ end
135
392
  end
136
393
  end
data/lib/rng/start.rb CHANGED
@@ -1,14 +1,63 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "lutaml/model"
2
- require_relative "element"
3
4
 
4
5
  module Rng
5
6
  class Start < Lutaml::Model::Serializable
6
- attribute :ref, :string
7
- attribute :elements, Element, collection: true
7
+ attribute :id, :string
8
+ attribute :ns, :string
9
+ attribute :datatypeLibrary, :string
10
+ attribute :combine, :string
11
+ attribute :ref, Ref
12
+ attribute :element, Element
13
+ attribute :choice, Choice
14
+ attribute :group, Group
15
+ attribute :interleave, Interleave
16
+ attribute :mixed, Mixed
17
+ attribute :optional, Optional
18
+ attribute :zeroOrMore, ZeroOrMore
19
+ attribute :oneOrMore, OneOrMore
20
+ attribute :text, Text
21
+ attribute :empty, Empty
22
+ attribute :value, Value
23
+ attribute :data, Data
24
+ attribute :list, List
25
+ attribute :parentRef, ParentRef
26
+ attribute :notAllowed, NotAllowed
27
+ attribute :grammar, Grammar
8
28
 
9
29
  xml do
10
- map_attribute "ref", to: :ref
11
- map_element "element", to: :elements
30
+ root "start", ordered: true
31
+ namespace "http://relaxng.org/ns/structure/1.0"
32
+
33
+ map_attribute "id", to: :id
34
+ map_attribute "ns", to: :ns, value_map: {
35
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
36
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
37
+ }
38
+ map_attribute "datatypeLibrary", to: :datatypeLibrary, value_map: {
39
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
40
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
41
+ }
42
+ map_attribute "combine", to: :combine
43
+
44
+ map_element "ref", to: :ref
45
+ map_element "element", to: :element
46
+ map_element "choice", to: :choice
47
+ map_element "group", to: :group
48
+ map_element "interleave", to: :interleave
49
+ map_element "mixed", to: :mixed
50
+ map_element "optional", to: :optional
51
+ map_element "zeroOrMore", to: :zeroOrMore
52
+ map_element "oneOrMore", to: :oneOrMore
53
+ map_element "text", to: :text
54
+ map_element "empty", to: :empty
55
+ map_element "value", to: :value
56
+ map_element "data", to: :data
57
+ map_element "list", to: :list
58
+ map_element "parentRef", to: :parentRef
59
+ map_element "notAllowed", to: :notAllowed
60
+ map_element "grammar", to: :grammar
12
61
  end
13
62
  end
14
63
  end
data/lib/rng/text.rb ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Rng
6
+ class Text < Lutaml::Model::Serializable
7
+ attribute :id, :string
8
+ attribute :ns, :string
9
+ attribute :datatypeLibrary, :string
10
+ attribute :value, :string, default: ""
11
+
12
+ xml do
13
+ root "text"
14
+ map_attribute "id", to: :id
15
+ map_attribute "ns", to: :ns, value_map: {
16
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
17
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
18
+ }
19
+ map_attribute "datatypeLibrary", to: :datatypeLibrary, value_map: {
20
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
21
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
22
+ }
23
+ map_content to: :value
24
+ end
25
+ end
26
+ end
data/lib/rng/to_rnc.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rng
4
+ # RNG to RNC converter module
5
+ # Provides functionality to convert RELAX NG XML Schema (RNG) to RELAX NG Compact Syntax (RNC)
6
+ module ToRnc
7
+ class << self
8
+ # Convert an RNG schema object to RNC syntax
9
+ # @param schema [Rng::Grammar] The schema to convert
10
+ # @return [String] The RNC representation of the schema
11
+ def convert(schema)
12
+ # This is a placeholder implementation
13
+ # The actual conversion logic would need to be implemented
14
+
15
+ # Return a simple template indicating this is a stub
16
+ "# RELAX NG Compact Syntax (RNC) - STUB IMPLEMENTATION\n" \
17
+ "# This is a placeholder for the actual RNG to RNC conversion\n\n" \
18
+ "start = element #{element_name(schema)} {\n" \
19
+ " # Conversion not yet implemented\n" \
20
+ " text\n" \
21
+ "}\n"
22
+ end
23
+
24
+ private
25
+
26
+ # Extract a sensible element name from the schema
27
+ # @param schema [Rng::Grammar] The schema to extract element name from
28
+ # @return [String] The element name or a default
29
+ def element_name(schema)
30
+ # Try to determine the root element name from the schema
31
+ if schema.respond_to?(:start) &&
32
+ schema.start.respond_to?(:element) &&
33
+ schema.start.element.any? &&
34
+ schema.start.element.first.respond_to?(:name)
35
+ return schema.start.element.first.name
36
+ end
37
+
38
+ # Try other options if available
39
+ if schema.respond_to?(:element) &&
40
+ schema.element.respond_to?(:name) &&
41
+ schema.element.name.is_a?(String)
42
+ return schema.element.name
43
+ end
44
+
45
+ # Use default name if we can't determine from schema
46
+ "root"
47
+ end
48
+ end
49
+ end
50
+
51
+ # Add class-level conversion method
52
+ def self.to_rnc(schema)
53
+ ToRnc.convert(schema)
54
+ end
55
+ end
data/lib/rng/value.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Rng
6
+ class Value < Lutaml::Model::Serializable
7
+ attribute :id, :string
8
+ attribute :ns, :string
9
+ attribute :datatypeLibrary, :string
10
+ attribute :type, :string
11
+ attribute :value, :string
12
+
13
+ xml do
14
+ root "value"
15
+
16
+ map_attribute "type", to: :type
17
+ map_attribute "id", to: :id
18
+ map_attribute "ns", to: :ns, value_map: {
19
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
20
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
21
+ }
22
+ map_attribute "datatypeLibrary", to: :datatypeLibrary, value_map: {
23
+ from: { empty: :empty, omitted: :omitted, nil: :nil },
24
+ to: { empty: :empty, omitted: :omitted, nil: :nil }
25
+ }
26
+ map_content to: :value
27
+ end
28
+ end
29
+ end
data/lib/rng/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rng
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end