moxml 0.1.3 → 0.1.6

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.rubocop_todo.yml +48 -20
  4. data/Gemfile +3 -0
  5. data/LICENSE.md +33 -0
  6. data/README.adoc +95 -23
  7. data/lib/moxml/adapter/base.rb +20 -2
  8. data/lib/moxml/adapter/customized_ox/attribute.rb +29 -0
  9. data/lib/moxml/adapter/customized_ox/namespace.rb +34 -0
  10. data/lib/moxml/adapter/customized_ox/text.rb +12 -0
  11. data/lib/moxml/adapter/customized_rexml/formatter.rb +195 -0
  12. data/lib/moxml/adapter/nokogiri.rb +4 -2
  13. data/lib/moxml/adapter/oga.rb +25 -9
  14. data/lib/moxml/adapter/ox.rb +238 -92
  15. data/lib/moxml/adapter/rexml.rb +462 -0
  16. data/lib/moxml/adapter.rb +1 -1
  17. data/lib/moxml/attribute.rb +2 -2
  18. data/lib/moxml/cdata.rb +0 -4
  19. data/lib/moxml/comment.rb +0 -4
  20. data/lib/moxml/config.rb +1 -1
  21. data/lib/moxml/context.rb +2 -2
  22. data/lib/moxml/doctype.rb +1 -5
  23. data/lib/moxml/document.rb +1 -1
  24. data/lib/moxml/document_builder.rb +14 -18
  25. data/lib/moxml/element.rb +4 -3
  26. data/lib/moxml/namespace.rb +5 -1
  27. data/lib/moxml/node.rb +17 -2
  28. data/lib/moxml/node_set.rb +8 -1
  29. data/lib/moxml/processing_instruction.rb +0 -4
  30. data/lib/moxml/text.rb +0 -4
  31. data/lib/moxml/version.rb +1 -1
  32. data/lib/ox/node.rb +9 -0
  33. data/spec/fixtures/small.xml +1 -0
  34. data/spec/moxml/adapter/rexml_spec.rb +14 -0
  35. data/spec/moxml/all_with_adapters_spec.rb +2 -3
  36. data/spec/support/shared_examples/builder.rb +19 -2
  37. data/spec/support/shared_examples/cdata.rb +7 -5
  38. data/spec/support/shared_examples/declaration.rb +17 -4
  39. data/spec/support/shared_examples/doctype.rb +2 -1
  40. data/spec/support/shared_examples/document.rb +10 -0
  41. data/spec/support/shared_examples/edge_cases.rb +9 -3
  42. data/spec/support/shared_examples/element.rb +5 -1
  43. data/spec/support/shared_examples/examples/benchmark_spec.rb +51 -0
  44. data/spec/support/shared_examples/examples/memory.rb +30 -17
  45. data/spec/support/shared_examples/examples/readme_examples.rb +5 -0
  46. data/spec/support/shared_examples/examples/thread_safety.rb +2 -0
  47. data/spec/support/shared_examples/examples/xpath.rb +34 -3
  48. data/spec/support/shared_examples/integration.rb +6 -2
  49. data/spec/support/shared_examples/namespace.rb +16 -0
  50. data/spec/support/shared_examples/node.rb +4 -0
  51. data/spec/support/shared_examples/node_set.rb +20 -0
  52. data/spec/support/shared_examples/processing_instruction.rb +1 -1
  53. data/spec/support/shared_examples/text.rb +2 -1
  54. data/spec/support/shared_examples/xml_adapter.rb +169 -7
  55. metadata +13 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7aeebdab58434af19ecef2aef1d8be83f44aa4cafef5386cc01f90df9c0d74b0
4
- data.tar.gz: 365ea23544a86eb5fbe13d6c87a903c844db321ba7884521ba76c4f169558bd2
3
+ metadata.gz: 90a6a09c55ff15198efd4687fa31e58bc4b17fa6a72b46c0e9cb88d5474f8899
4
+ data.tar.gz: 27b376ff3bfa49b2bcb7c768451af8e39f491a7e2467c6965e85cee3cedc43f9
5
5
  SHA512:
6
- metadata.gz: 924f7a2e7e6a68d9e78f4f65244bd5f8cdaefa58c00dc7a3a926d2cb41d1d6ac39cc98c46cdd83f13dbdec450ad5b8abbe400c6b89a595aadf2e1c21f074ab01
7
- data.tar.gz: f125a15ea901391a648a3545b5afa79d9e3794c4e5f4009c6cca623501ad53071f27fbc3046da7fe0a964a240c8d9ae7f75410283f59daa0b6a34ac561540c68
6
+ metadata.gz: 3895bfc0612eddea337e083e6cdd66dbfda811d7d819c858d05a7e30b433c226ddaa8e7995690c65f142b329ac9454c8712c1cb9f6d95372c8cbbc0b0c8e7846
7
+ data.tar.gz: 52bf943812996dcd501d65dfe2d6f9b06578429de92fe2ad74f87080c1c57cc04a8574c3e85ad72f156918d5ada2415c8e4a4c5e97ff2f10d68b5056d821c599
data/.gitignore CHANGED
@@ -1,4 +1,3 @@
1
- /.bundle/
2
1
  /.yardoc
3
2
  /_yardoc/
4
3
  /coverage/
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-02-07 04:56:30 UTC using RuboCop version 1.71.2.
3
+ # on 2025-05-09 11:52:41 UTC using RuboCop version 1.68.0.
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
@@ -17,39 +17,45 @@ Lint/MissingCopEnableDirective:
17
17
  Exclude:
18
18
  - 'lib/moxml/adapter/customized_oga/xml_generator.rb'
19
19
 
20
- # Offense count: 1
20
+ # Offense count: 2
21
21
  # Configuration parameters: AllowedParentClasses.
22
22
  Lint/MissingSuper:
23
23
  Exclude:
24
24
  - 'lib/moxml/adapter/customized_oga/xml_declaration.rb'
25
+ - 'lib/moxml/adapter/customized_rexml/formatter.rb'
25
26
 
26
- # Offense count: 5
27
+ # Offense count: 8
27
28
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
28
29
  Metrics/AbcSize:
29
- Max: 30
30
+ Max: 39
30
31
 
31
- # Offense count: 49
32
+ # Offense count: 53
32
33
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
33
34
  # AllowedMethods: refine
34
35
  Metrics/BlockLength:
35
- Max: 152
36
+ Max: 270
36
37
 
37
- # Offense count: 3
38
+ # Offense count: 5
38
39
  # Configuration parameters: CountComments, CountAsOne.
39
40
  Metrics/ClassLength:
40
- Max: 246
41
+ Max: 373
41
42
 
42
- # Offense count: 3
43
+ # Offense count: 7
43
44
  # Configuration parameters: AllowedMethods, AllowedPatterns.
44
45
  Metrics/CyclomaticComplexity:
45
- Max: 10
46
+ Max: 15
46
47
 
47
- # Offense count: 9
48
+ # Offense count: 15
48
49
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
49
50
  Metrics/MethodLength:
50
- Max: 20
51
+ Max: 23
51
52
 
52
- # Offense count: 4
53
+ # Offense count: 3
54
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
55
+ Metrics/PerceivedComplexity:
56
+ Max: 16
57
+
58
+ # Offense count: 5
53
59
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
54
60
  # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
55
61
  Naming/MethodParameterName:
@@ -57,17 +63,39 @@ Naming/MethodParameterName:
57
63
  - 'lib/moxml/adapter/customized_oga/xml_generator.rb'
58
64
  - 'lib/moxml/adapter/nokogiri.rb'
59
65
  - 'lib/moxml/adapter/ox.rb'
66
+ - 'lib/moxml/adapter/rexml.rb'
60
67
  - 'lib/moxml/attribute.rb'
61
68
 
62
- # Offense count: 27
69
+ # Offense count: 1
70
+ # This cop supports unsafe autocorrection (--autocorrect-all).
71
+ Style/CombinableLoops:
72
+ Exclude:
73
+ - 'lib/moxml/adapter/customized_rexml/formatter.rb'
74
+
75
+ # Offense count: 28
63
76
  # Configuration parameters: AllowedConstants.
64
77
  Style/Documentation:
65
78
  Enabled: false
66
79
 
67
- # Offense count: 20
68
- # This cop supports safe autocorrection (--autocorrect).
69
- # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
70
- # SupportedStyles: single_quotes, double_quotes
71
- Style/StringLiterals:
80
+ # Offense count: 1
81
+ # This cop supports unsafe autocorrection (--autocorrect-all).
82
+ # Configuration parameters: EnforcedStyle.
83
+ # SupportedStyles: always, always_true, never
84
+ Style/FrozenStringLiteralComment:
85
+ Exclude:
86
+ - 'lib/moxml/adapter/customized_rexml/formatter.rb'
87
+
88
+ # Offense count: 2
89
+ # Configuration parameters: MinBranchesCount.
90
+ Style/HashLikeCase:
91
+ Exclude:
92
+ - 'lib/moxml/adapter/customized_rexml/formatter.rb'
93
+
94
+ # Offense count: 2
95
+ # This cop supports unsafe autocorrection (--autocorrect-all).
96
+ # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
97
+ # AllowedMethods: present?, blank?, presence, try, try!
98
+ Style/SafeNavigation:
72
99
  Exclude:
73
- - 'spec/support/shared_examples/examples/readme_examples.rb'
100
+ - 'lib/moxml/adapter/customized_rexml/formatter.rb'
101
+ - 'lib/moxml/adapter/rexml.rb'
data/Gemfile CHANGED
@@ -11,9 +11,12 @@ gem "nokogiri", "~> 1.15"
11
11
  gem "oga", "~> 3.4"
12
12
  gem "ox", "~> 2.14"
13
13
  gem "rake", "~> 13"
14
+ gem "rexml"
14
15
  gem "rspec", "~> 3.0"
15
16
  gem "rubocop", "~> 1.21"
16
17
  gem "tempfile", "~> 0.3"
18
+ # Provides iteration per second benchmarking for Ruby
19
+ gem "benchmark-ips"
17
20
 
18
21
  # Needed by get_process_mem on Windows
19
22
  gem "sys-proctable" if Gem.win_platform?
data/LICENSE.md ADDED
@@ -0,0 +1,33 @@
1
+ Licenses & Copyright
2
+ ====================
3
+
4
+ This license file adheres to the formatting guidelines of
5
+ [readable-licenses](https://github.com/nevir/readable-licenses).
6
+
7
+
8
+ Ribose's BSD 2-Clause License
9
+ -----------------------------
10
+
11
+ Copyright (c) 2024, [Ribose Inc](https://www.ribose.com).
12
+ All rights reserved.
13
+
14
+ Redistribution and use in source and binary forms, with or without modification,
15
+ are permitted provided that the following conditions are met:
16
+
17
+ 1. Redistributions of source code must retain the above copyright notice,
18
+ this list of conditions and the following disclaimer.
19
+
20
+ 2. Redistributions in binary form must reproduce the above copyright notice,
21
+ this list of conditions and the following disclaimer in the documentation
22
+ and/or other materials provided with the distribution.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
28
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.adoc CHANGED
@@ -24,15 +24,80 @@ Key features:
24
24
  * Easy switching between XML processing engines
25
25
  * Clean separation between interface and implementation
26
26
 
27
+ == Supported XML libraries
28
+
29
+ Moxml supports the following XML libraries:
30
+
31
+ REXML:: https://github.com/ruby/rexml[REXML], a pure Ruby XML parser
32
+ distributed with standard Ruby. Not the fastest, but always available.
33
+
34
+ Nokogiri:: (default) https://github.com/sparklemotion/nokogiri[Nokogiri], a
35
+ widely used implementation which wraps around the performant
36
+ https://github.com/GNOME/libxml2[libxml2] C library.
37
+
38
+ Oga:: https://github.com/yorickpeterse/oga[Oga], a pure Ruby XML parser.
39
+ Recommended when you need a pure Ruby solution say for
40
+ https://github.com/opal/opal[Opal].
41
+
42
+ Ox:: https://github.com/ohler55/ox[Ox], a fast XML parser.
43
+
44
+ === Feature table
45
+
46
+ Moxml exercises its best effort to provide a consistent interface across basic
47
+ XML features, various XML libraries have different features and capabilities.
48
+
49
+ The following table summarizes the features supported by each library.
50
+
51
+ NOTE: The checkmarks indicate support for the feature, while the footnotes
52
+ provide additional context for specific features.
53
+
54
+ [cols="1,1,1,1,3"]
55
+ |===
56
+ |Feature |Nokogiri |Oga |REXML |Ox
57
+
58
+ |Parsing, serializing
59
+ | ✅
60
+ | ✅
61
+ | ✅
62
+ | ✅
63
+
64
+ |Node manipulation
65
+ | ✅
66
+ | ✅
67
+ | ✅
68
+ | ✅ See NOTE 1.
69
+
70
+ |Basic XPath
71
+ | ✅
72
+ | ✅
73
+ | ✅
74
+ a|
75
+ Uses `locate`. See NOTE 2.
76
+
77
+ |XPath with namespaces
78
+ | ✅
79
+ | ✅
80
+ | ❌
81
+ a|
82
+ Uses `locate`. See NOTE 2.
83
+
84
+ |===
85
+
86
+ NOTE 1: Ox's node manipulation may have issues, especially when manipulating Text nodes.
87
+
88
+ NOTE 2: The native Ox method `locate` is similar to XPath but has a different syntax.
89
+
27
90
  == Getting started
28
91
 
92
+ === Installation
93
+
29
94
  Install the gem and at least one supported XML library:
30
95
 
31
96
  [source,ruby]
32
97
  ----
33
98
  # In your Gemfile
34
99
  gem 'moxml'
35
- gem 'nokogiri' # Or 'oga', or 'ox' when it is integrated
100
+ gem 'nokogiri' # Or 'oga', 'rexml', or 'ox'
36
101
  ----
37
102
 
38
103
  === Basic document creation
@@ -228,7 +293,7 @@ text.text? # Returns true
228
293
 
229
294
  # Structure
230
295
  text.parent # Get parent node
231
- text.remove # Remove from document
296
+ text.remove # Remove from document
232
297
  text.replace(node) # Replace with another node
233
298
  ----
234
299
 
@@ -250,7 +315,7 @@ cdata.cdata? # Returns true
250
315
 
251
316
  # Structure
252
317
  cdata.parent # Get parent node
253
- cdata.remove # Remove from document
318
+ cdata.remove # Remove from document
254
319
  cdata.replace(node) # Replace with another node
255
320
  ----
256
321
 
@@ -289,7 +354,7 @@ pi = doc.create_processing_instruction("xml-stylesheet",
289
354
  # PI properties
290
355
  pi.target # Get PI target
291
356
  pi.target = "new" # Set PI target
292
- pi.content # Get PI content
357
+ pi.content # Get PI content
293
358
  pi.content = "new" # Set PI content
294
359
 
295
360
  # Node type checking
@@ -297,7 +362,7 @@ pi.processing_instruction? # Returns true
297
362
 
298
363
  # Structure
299
364
  pi.parent # Get parent node
300
- pi.remove # Remove from document
365
+ pi.remove # Remove from document
301
366
  pi.replace(node) # Replace with another node
302
367
  ----
303
368
 
@@ -344,15 +409,13 @@ Each node type provides methods for traversing the document structure:
344
409
 
345
410
  [source,ruby]
346
411
  ----
347
- node.parent # Get parent node
412
+ node.parent # Get parent node
348
413
  node.children # Get child nodes
349
414
  node.next_sibling # Get next sibling
350
415
  node.previous_sibling # Get previous sibling
351
- node.ancestors # Get all ancestor nodes
352
- node.descendants # Get all descendant nodes
353
416
 
354
417
  # Type checking
355
- node.element? # Is it an element?
418
+ node.element? # Is it an element?
356
419
  node.text? # Is it a text node?
357
420
  node.cdata? # Is it a CDATA section?
358
421
  node.comment? # Is it a comment?
@@ -362,14 +425,14 @@ node.namespace? # Is it a namespace?
362
425
 
363
426
  # Node information
364
427
  node.document # Get owning document
365
- node.path # Get XPath to node
366
- node.line_number # Get source line number (if available)
367
428
  ----
368
429
 
369
430
  == Advanced features
370
431
 
371
432
  === XPath querying and node mapping
372
433
 
434
+ ==== Nokogiri, Oga, REXML
435
+
373
436
  Moxml provides efficient XPath querying by leveraging the native XML library's
374
437
  implementation while maintaining consistent node mapping:
375
438
 
@@ -394,6 +457,12 @@ doc.xpath('//book').each do |book|
394
457
  end
395
458
  ----
396
459
 
460
+ ==== Ox
461
+
462
+ The native Ox's query method
463
+ https://www.ohler.com/ox/Ox/Element.html#method-i-locate[`locate`] resembles
464
+ XPath but has a different syntax.
465
+
397
466
  === Namespace handling
398
467
 
399
468
  [source,ruby]
@@ -478,22 +547,23 @@ end
478
547
 
479
548
  === Default adapter selection
480
549
 
481
- To use an adapter other than `:nokogiri` as the global default, set it before
482
- processing any input using the following option.
550
+ To select a non-default adapter, set it before processing any input using the
551
+ following syntax.
483
552
 
484
553
  [source,ruby]
485
554
  ----
486
555
  Moxml::Config.default_adapter = <adapter-symbol>
487
556
  ----
488
557
 
489
- Moxml supports the following adapters:
558
+ Where, `<adapter-symbol>` is one of the following:
490
559
 
491
- `:nokogiri`:: (default) https://github.com/sparklemotion/nokogiri[Nokogiri], a
492
- wrapper around the https://github.com/GNOME/libxml2[libxml2] C library
560
+ `:rexml`:: REXML
493
561
 
494
- `:oga`:: https://github.com/yorickpeterse/oga[Oga], a pure Ruby XML parser
562
+ `:nokogiri`:: Nokogiri (default)
495
563
 
496
- `:ox`:: https://github.com/ohler55/ox[Ox], a fast XML parser (not yet supported)
564
+ `:oga`:: Oga
565
+
566
+ `:ox`:: Ox
497
567
 
498
568
 
499
569
  == Thread safety
@@ -546,7 +616,7 @@ doc.xpath('//book/title')
546
616
  doc.xpath('//title')
547
617
 
548
618
  # Most efficient - direct child access
549
- root.xpath('./title')
619
+ root.xpath('./*/title')
550
620
  ----
551
621
 
552
622
  == Best practices
@@ -556,7 +626,7 @@ root.xpath('./title')
556
626
  [source,ruby]
557
627
  ----
558
628
  # Preferred - using builder pattern
559
- doc = Moxml.new.build do
629
+ doc = Moxml::Builder.new(Moxml.new).build do
560
630
  declaration version: "1.0", encoding: "UTF-8"
561
631
  element 'root' do
562
632
  element 'child' do
@@ -567,7 +637,7 @@ end
567
637
 
568
638
  # Alternative - direct manipulation
569
639
  doc = Moxml.new.create_document
570
- doc.add_declaration(version: "1.0", encoding: "UTF-8")
640
+ doc.add_child(doc.create_declaration("1.0", "UTF-8"))
571
641
  root = doc.create_element('root')
572
642
  doc.add_child(root)
573
643
  ----
@@ -583,6 +653,7 @@ element
583
653
 
584
654
  # Preferred - clear node type checking
585
655
  if node.element?
656
+ node.add_namespace('dc', 'http://purl.org/dc/elements/1.1/')
586
657
  node.add_child(doc.create_text('content'))
587
658
  end
588
659
  ----
@@ -597,7 +668,8 @@ end
597
668
 
598
669
  == License
599
670
 
600
- Copyright (c) 2024 Ribose Inc.
671
+ Copyright Ribose.
601
672
 
602
- This project is licensed under the BSD-2-Clause License. See the LICENSE file for details.
673
+ This project is licensed under the BSD-2-Clause License. See the
674
+ link:LICENSE.md[] file for details.
603
675
 
@@ -19,7 +19,7 @@ module Moxml
19
19
  raise NotImplementedError
20
20
  end
21
21
 
22
- def create_document
22
+ def create_document(native_doc = nil)
23
23
  raise NotImplementedError
24
24
  end
25
25
 
@@ -29,7 +29,8 @@ module Moxml
29
29
  end
30
30
 
31
31
  def create_text(content)
32
- create_native_text(normalize_xml_value(content))
32
+ # Ox freezes the content, so we need to dup it
33
+ create_native_text(normalize_xml_value(content).dup)
33
34
  end
34
35
 
35
36
  def create_cdata(content)
@@ -63,6 +64,23 @@ module Moxml
63
64
  create_native_namespace(element, prefix, uri)
64
65
  end
65
66
 
67
+ def set_attribute_name(attribute, name)
68
+ attribute.name = name
69
+ end
70
+
71
+ def set_attribute_value(attribute, value)
72
+ attribute.value = value
73
+ end
74
+
75
+ def duplicate_node(node)
76
+ node.dup
77
+ end
78
+
79
+ def patch_node(node, _parent = nil)
80
+ # monkey-patch the native node if necessary
81
+ node
82
+ end
83
+
66
84
  protected
67
85
 
68
86
  def create_native_element(name)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../ox/node"
4
+
5
+ module Moxml
6
+ module Adapter
7
+ module CustomizedOx
8
+ class Attribute < ::Ox::Node
9
+ attr_reader :name, :prefix
10
+
11
+ def initialize(attr_name, value, parent = nil)
12
+ self.name = attr_name
13
+ @parent = parent
14
+ super(value)
15
+ end
16
+
17
+ def name=(new_name)
18
+ @prefix, new_name = new_name.to_s.split(":", 2) if new_name.to_s.include?(":")
19
+
20
+ @name = new_name
21
+ end
22
+
23
+ def expanded_name
24
+ [prefix, name].compact.join(":")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../ox/node"
4
+
5
+ module Moxml
6
+ module Adapter
7
+ module CustomizedOx
8
+ class Namespace
9
+ attr_accessor :uri, :parent
10
+ attr_writer :prefix
11
+
12
+ def initialize(prefix, uri, parent = nil)
13
+ @prefix = prefix
14
+ @uri = uri
15
+ @parent = parent
16
+ end
17
+
18
+ def prefix
19
+ return if @prefix == "xmlns" || @prefix.nil?
20
+
21
+ @prefix.to_s.delete_prefix("xmlns:")
22
+ end
23
+
24
+ def expanded_prefix
25
+ ["xmlns", prefix].compact.join(":")
26
+ end
27
+
28
+ def default?
29
+ prefix.nil?
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../../ox/node"
4
+
5
+ module Moxml
6
+ module Adapter
7
+ module CustomizedOx
8
+ # Ox uses Strings, but a string cannot have a parent reference
9
+ class Text < ::Ox::Node; end
10
+ end
11
+ end
12
+ end