moxml 0.1.23 → 0.1.24
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/Rakefile +1 -1
- data/lib/compat/opal/moxml_boot.rb +53 -0
- data/lib/moxml/adapter/base.rb +5 -5
- data/lib/moxml/adapter/customized_libxml/cdata.rb +0 -2
- data/lib/moxml/adapter/customized_libxml/comment.rb +0 -2
- data/lib/moxml/adapter/customized_libxml/element.rb +3 -5
- data/lib/moxml/adapter/customized_libxml/node.rb +2 -2
- data/lib/moxml/adapter/customized_libxml/processing_instruction.rb +0 -2
- data/lib/moxml/adapter/customized_libxml/text.rb +0 -2
- data/lib/moxml/adapter/customized_rexml/formatter.rb +3 -4
- data/lib/moxml/adapter/headed_ox.rb +1 -5
- data/lib/moxml/adapter/libxml.rb +12 -10
- data/lib/moxml/adapter/nokogiri.rb +4 -2
- data/lib/moxml/adapter/oga.rb +10 -10
- data/lib/moxml/adapter/ox.rb +29 -16
- data/lib/moxml/adapter/rexml.rb +5 -6
- data/lib/moxml/adapter.rb +12 -4
- data/lib/moxml/attribute.rb +5 -2
- data/lib/moxml/config.rb +1 -0
- data/lib/moxml/context.rb +8 -8
- data/lib/moxml/declaration.rb +2 -7
- data/lib/moxml/document.rb +0 -11
- data/lib/moxml/document_builder.rb +12 -8
- data/lib/moxml/element.rb +4 -4
- data/lib/moxml/node.rb +37 -14
- data/lib/moxml/node_set.rb +2 -4
- data/lib/moxml/sax/block_handler.rb +0 -2
- data/lib/moxml/sax/element_handler.rb +0 -2
- data/lib/moxml/sax/namespace_splitter.rb +5 -4
- data/lib/moxml/sax.rb +4 -25
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xml_utils.rb +1 -3
- data/lib/moxml/xpath/compiler.rb +1 -49
- data/lib/moxml/xpath/conversion.rb +7 -6
- data/lib/moxml/xpath/ruby/generator.rb +12 -19
- data/lib/moxml/xpath/ruby/node.rb +1 -9
- data/lib/moxml/xpath.rb +6 -14
- data/lib/moxml.rb +67 -20
- data/spec/moxml/attribute_spec.rb +16 -0
- data/spec/moxml/context_spec.rb +14 -0
- data/spec/moxml/moxml_spec.rb +13 -0
- data/spec/moxml/node_spec.rb +58 -0
- data/spec/moxml/xpath/ruby/node_spec.rb +3 -3
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c61c5dcecbe10b9f0f2850a134c9a8c5e2ec7d0be5b5b1dbb828dac25019a55
|
|
4
|
+
data.tar.gz: f418e1f7a7406bfcc0dd9e57bc2a6b372a332b0e6677821a9e2b7a8173871b45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 44ccdeb45ec15bdadb02a470bd8506f051ee22385a0832b78d17b607ef32a192b28f0ec716f7910f2ba22c106b0a48ffec85aaaf1dbe33f7ce4a1f4fd7108695
|
|
7
|
+
data.tar.gz: 49ed1641cd66fe4efa02f0e072b07621f441e3936734aba4ebb58a2f9188fab5feae920c989b21476019b01fac1562afc36356059d4c979f9a41b8f3e29686ec
|
data/Rakefile
CHANGED
|
@@ -35,7 +35,7 @@ namespace :spec do
|
|
|
35
35
|
|
|
36
36
|
runner.default_path = "spec"
|
|
37
37
|
runner.requires = %w[rexml_compat rexml/document rexml/xpath
|
|
38
|
-
|
|
38
|
+
moxml_boot spec_helper support/opal]
|
|
39
39
|
runner.files = Dir.glob("spec/moxml/*opal*_spec.rb") +
|
|
40
40
|
Dir.glob("spec/moxml/native_attachment/opal_spec.rb") +
|
|
41
41
|
Dir.glob("spec/moxml/adapter/shared_examples/*.rb")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Opal doesn't support Ruby autoload. This file explicitly requires
|
|
4
|
+
# all Moxml modules that would normally be lazy-loaded via autoload
|
|
5
|
+
# in lib/moxml.rb. Loaded by the Opal Rakefile before spec_helper.
|
|
6
|
+
|
|
7
|
+
require "moxml/version"
|
|
8
|
+
require "moxml/error"
|
|
9
|
+
require "moxml/native_attachment"
|
|
10
|
+
require "moxml/native_attachment/opal"
|
|
11
|
+
require "moxml/xml_utils"
|
|
12
|
+
require "moxml/xml_utils/encoder"
|
|
13
|
+
require "moxml/node"
|
|
14
|
+
require "moxml/node_set"
|
|
15
|
+
require "moxml/document"
|
|
16
|
+
require "moxml/element"
|
|
17
|
+
require "moxml/attribute"
|
|
18
|
+
require "moxml/text"
|
|
19
|
+
require "moxml/cdata"
|
|
20
|
+
require "moxml/comment"
|
|
21
|
+
require "moxml/processing_instruction"
|
|
22
|
+
require "moxml/declaration"
|
|
23
|
+
require "moxml/namespace"
|
|
24
|
+
require "moxml/doctype"
|
|
25
|
+
require "moxml/entity_reference"
|
|
26
|
+
require "moxml/entity_registry"
|
|
27
|
+
require "moxml/adapter"
|
|
28
|
+
require "moxml/adapter/base"
|
|
29
|
+
require "moxml/adapter/customized_rexml"
|
|
30
|
+
require "moxml/adapter/customized_rexml/entity_reference"
|
|
31
|
+
require "moxml/adapter/customized_rexml/formatter"
|
|
32
|
+
require "moxml/sax"
|
|
33
|
+
require "moxml/sax/handler"
|
|
34
|
+
require "moxml/sax/element_handler"
|
|
35
|
+
require "moxml/sax/block_handler"
|
|
36
|
+
require "moxml/sax/namespace_splitter"
|
|
37
|
+
require "moxml/adapter/rexml"
|
|
38
|
+
require "moxml/document_builder"
|
|
39
|
+
require "moxml/builder"
|
|
40
|
+
require "moxml/context"
|
|
41
|
+
require "moxml/config"
|
|
42
|
+
require "moxml/xpath"
|
|
43
|
+
require "moxml/xpath/engine"
|
|
44
|
+
require "moxml/xpath/context"
|
|
45
|
+
require "moxml/xpath/conversion"
|
|
46
|
+
require "moxml/xpath/cache"
|
|
47
|
+
require "moxml/xpath/lexer"
|
|
48
|
+
require "moxml/xpath/parser"
|
|
49
|
+
require "moxml/xpath/compiler"
|
|
50
|
+
require "moxml/xpath/errors"
|
|
51
|
+
require "moxml/xpath/ast/node"
|
|
52
|
+
require "moxml/xpath/ruby/node"
|
|
53
|
+
require "moxml/xpath/ruby/generator"
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "../xml_utils"
|
|
4
|
-
require_relative "../document_builder"
|
|
5
|
-
|
|
6
3
|
module Moxml
|
|
7
4
|
module Adapter
|
|
8
5
|
class Base
|
|
@@ -104,8 +101,7 @@ module Moxml
|
|
|
104
101
|
#
|
|
105
102
|
# @return [Boolean] true if SAX parsing is supported
|
|
106
103
|
def sax_supported?
|
|
107
|
-
|
|
108
|
-
method(:sax_parse).owner != Moxml::Adapter::Base.singleton_class
|
|
104
|
+
method(:sax_parse).owner != Moxml::Adapter::Base.singleton_class
|
|
109
105
|
end
|
|
110
106
|
|
|
111
107
|
def create_document(_native_doc = nil)
|
|
@@ -212,6 +208,10 @@ namespace_validation_mode: :strict)
|
|
|
212
208
|
wrapper.has_xml_declaration
|
|
213
209
|
end
|
|
214
210
|
|
|
211
|
+
# Clear the declaration state from the native document.
|
|
212
|
+
# Called when a Declaration node is removed from a document.
|
|
213
|
+
def remove_declaration(_native_doc); end
|
|
214
|
+
|
|
215
215
|
# Return the actual native node after an add_child operation.
|
|
216
216
|
# Override for adapters where node identity may change (e.g., LibXML doc.root=).
|
|
217
217
|
def actual_native(child_native, _parent_native)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "node"
|
|
4
|
-
|
|
5
3
|
module Moxml
|
|
6
4
|
module Adapter
|
|
7
5
|
module CustomizedLibxml
|
|
@@ -12,7 +10,7 @@ module Moxml
|
|
|
12
10
|
class Element < Node
|
|
13
11
|
# Add a child to this element, handling document import automatically
|
|
14
12
|
def add_child(child)
|
|
15
|
-
child_native = child.
|
|
13
|
+
child_native = child.is_a?(Node) ? child.native : child
|
|
16
14
|
|
|
17
15
|
# Check if child needs to be imported
|
|
18
16
|
if needs_import?(child_native)
|
|
@@ -26,9 +24,9 @@ module Moxml
|
|
|
26
24
|
private
|
|
27
25
|
|
|
28
26
|
def needs_import?(child_node)
|
|
29
|
-
return false unless @native.
|
|
27
|
+
return false unless @native.is_a?(::LibXML::XML::Node)
|
|
30
28
|
return false unless @native.doc
|
|
31
|
-
return false unless child_node.
|
|
29
|
+
return false unless child_node.is_a?(::LibXML::XML::Node)
|
|
32
30
|
return false unless child_node.doc
|
|
33
31
|
|
|
34
32
|
child_node.doc != @native.doc
|
|
@@ -22,7 +22,7 @@ module Moxml
|
|
|
22
22
|
def ==(other)
|
|
23
23
|
return false unless other
|
|
24
24
|
|
|
25
|
-
other_native = other.
|
|
25
|
+
other_native = other.is_a?(self.class) ? other.native : other
|
|
26
26
|
@native == other_native
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -34,7 +34,7 @@ module Moxml
|
|
|
34
34
|
|
|
35
35
|
# Check if node has a document
|
|
36
36
|
def document_present?
|
|
37
|
-
@native.
|
|
37
|
+
@native.is_a?(::LibXML::XML::Node) && !@native.doc.nil?
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Get the document this node belongs to
|
|
@@ -185,9 +185,8 @@ module Moxml
|
|
|
185
185
|
node.attributes.each do |name, attr|
|
|
186
186
|
next unless name.to_s.start_with?("xmlns:") || name.to_s == "xmlns"
|
|
187
187
|
|
|
188
|
-
# convert the default namespace
|
|
189
188
|
name = "xmlns" if name.to_s == "xmlns:"
|
|
190
|
-
value = attr.
|
|
189
|
+
value = attr.is_a?(::REXML::Attribute) ? attr.value : attr
|
|
191
190
|
output << " #{name}=\"#{value}\""
|
|
192
191
|
end
|
|
193
192
|
|
|
@@ -196,14 +195,14 @@ module Moxml
|
|
|
196
195
|
next if name.to_s.start_with?("xmlns:") || name.to_s == "xmlns"
|
|
197
196
|
|
|
198
197
|
output << " "
|
|
199
|
-
output << if attr.
|
|
198
|
+
output << if attr.is_a?(::REXML::Attribute) && attr.prefix
|
|
200
199
|
"#{attr.prefix}:#{attr.name}"
|
|
201
200
|
else
|
|
202
201
|
name.to_s
|
|
203
202
|
end
|
|
204
203
|
|
|
205
204
|
output << "=\""
|
|
206
|
-
value = attr.
|
|
205
|
+
value = attr.is_a?(::REXML::Attribute) ? attr.value : attr
|
|
207
206
|
output << escape_attribute_value(value.to_s)
|
|
208
207
|
output << "\""
|
|
209
208
|
end # rubocop:enable Style/CombinableLoops
|
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
return if RUBY_ENGINE == "opal"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
require_relative "../xpath"
|
|
7
|
-
# Force load XPath modules (autoload doesn't work well with relative requires in examples)
|
|
8
|
-
require_relative "../xpath/parser"
|
|
9
|
-
require_relative "../xpath/compiler"
|
|
5
|
+
require "moxml/adapter/ox"
|
|
10
6
|
|
|
11
7
|
module Moxml
|
|
12
8
|
module Adapter
|
data/lib/moxml/adapter/libxml.rb
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
return if RUBY_ENGINE == "opal"
|
|
4
4
|
|
|
5
|
-
require_relative "base"
|
|
6
5
|
require "libxml"
|
|
7
|
-
require_relative "customized_libxml"
|
|
8
|
-
require_relative "../sax/namespace_splitter"
|
|
9
6
|
|
|
10
7
|
module Moxml
|
|
11
8
|
module Adapter
|
|
12
9
|
class Libxml < Base
|
|
10
|
+
autoload :EntityRefRegistry, "moxml/adapter/libxml/entity_ref_registry"
|
|
11
|
+
autoload :EntityRestorer, "moxml/adapter/libxml/entity_restorer"
|
|
12
|
+
|
|
13
13
|
# Wrapper class to store DOCTYPE information
|
|
14
14
|
class DoctypeWrapper
|
|
15
15
|
attr_reader :native_doc
|
|
@@ -239,7 +239,7 @@ module Moxml
|
|
|
239
239
|
# Duck-typed fallback for libxml types that aren't ::Node
|
|
240
240
|
# subclasses but still expose node_type (e.g. ::Attr).
|
|
241
241
|
native = unpatch_node(node)
|
|
242
|
-
return :unknown unless native.
|
|
242
|
+
return :unknown unless native.is_a?(::LibXML::XML::Node)
|
|
243
243
|
|
|
244
244
|
NATIVE_NODE_TYPE_MAP[native.node_type] || :unknown
|
|
245
245
|
end
|
|
@@ -836,7 +836,7 @@ module Moxml
|
|
|
836
836
|
return [] unless namespaces
|
|
837
837
|
|
|
838
838
|
namespace_list =
|
|
839
|
-
if namespaces.
|
|
839
|
+
if namespaces.is_a?(::LibXML::XML::Namespaces)
|
|
840
840
|
namespaces.definitions
|
|
841
841
|
else
|
|
842
842
|
namespaces
|
|
@@ -1076,6 +1076,11 @@ module Moxml
|
|
|
1076
1076
|
end
|
|
1077
1077
|
end
|
|
1078
1078
|
|
|
1079
|
+
def remove_declaration(native_doc)
|
|
1080
|
+
decl = attachments.get(native_doc, :declaration)
|
|
1081
|
+
decl&.removed = true
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1079
1084
|
# LibXML's doc.root= creates a new Ruby wrapper with different object_id.
|
|
1080
1085
|
# Return the actual root node so attachments are stored on the correct object.
|
|
1081
1086
|
def actual_native(child_native, parent_native)
|
|
@@ -1319,7 +1324,7 @@ module Moxml
|
|
|
1319
1324
|
return unless elem.is_a?(::LibXML::XML::Node)
|
|
1320
1325
|
|
|
1321
1326
|
ns_list = elem.namespaces
|
|
1322
|
-
return unless ns_list.
|
|
1327
|
+
return unless ns_list.is_a?(::LibXML::XML::Namespaces)
|
|
1323
1328
|
|
|
1324
1329
|
definitions = ns_list.definitions
|
|
1325
1330
|
return if definitions.empty?
|
|
@@ -1551,7 +1556,7 @@ module Moxml
|
|
|
1551
1556
|
|
|
1552
1557
|
# Also check if this element has an active namespace (inherited or own)
|
|
1553
1558
|
# This catches cases where elements inherit namespaces from parents
|
|
1554
|
-
if node.is_a?(::LibXML::XML::Node) && node.namespaces.
|
|
1559
|
+
if node.is_a?(::LibXML::XML::Node) && node.namespaces.is_a?(::LibXML::XML::Namespaces)
|
|
1555
1560
|
active_ns = node.namespaces.namespace
|
|
1556
1561
|
if active_ns
|
|
1557
1562
|
prefix = active_ns.prefix
|
|
@@ -1720,6 +1725,3 @@ module Moxml
|
|
|
1720
1725
|
end
|
|
1721
1726
|
end
|
|
1722
1727
|
end
|
|
1723
|
-
|
|
1724
|
-
require_relative "libxml/entity_ref_registry"
|
|
1725
|
-
require_relative "libxml/entity_restorer"
|
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
return if RUBY_ENGINE == "opal"
|
|
4
4
|
|
|
5
|
-
require_relative "base"
|
|
6
5
|
require "nokogiri"
|
|
7
|
-
require_relative "../sax/namespace_splitter"
|
|
8
6
|
|
|
9
7
|
module Moxml
|
|
10
8
|
module Adapter
|
|
@@ -426,6 +424,10 @@ module Moxml
|
|
|
426
424
|
end
|
|
427
425
|
end
|
|
428
426
|
|
|
427
|
+
def remove_declaration(native_doc)
|
|
428
|
+
attachments.set(native_doc, :xml_decl, nil)
|
|
429
|
+
end
|
|
430
|
+
|
|
429
431
|
private
|
|
430
432
|
|
|
431
433
|
def build_declaration_attrs(version, encoding, standalone)
|
data/lib/moxml/adapter/oga.rb
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base"
|
|
4
|
-
require_relative "customized_oga"
|
|
5
3
|
require "oga"
|
|
6
|
-
require_relative "../sax/namespace_splitter"
|
|
7
4
|
|
|
8
5
|
module Moxml
|
|
9
6
|
module Adapter
|
|
@@ -470,13 +467,16 @@ module Moxml
|
|
|
470
467
|
def has_declaration?(native_doc, _wrapper)
|
|
471
468
|
decl = attachments.get(native_doc, :xml_declaration)
|
|
472
469
|
if decl.nil? && !attachments.key?(native_doc, :xml_declaration)
|
|
473
|
-
|
|
474
|
-
native_doc.respond_to?(:xml_declaration) && !native_doc.xml_declaration.nil?
|
|
470
|
+
native_doc.is_a?(::Oga::XML::Document) && !native_doc.xml_declaration.nil?
|
|
475
471
|
else
|
|
476
472
|
!decl.nil?
|
|
477
473
|
end
|
|
478
474
|
end
|
|
479
475
|
|
|
476
|
+
def remove_declaration(native_doc)
|
|
477
|
+
attachments.set(native_doc, :xml_declaration, nil)
|
|
478
|
+
end
|
|
479
|
+
|
|
480
480
|
private
|
|
481
481
|
|
|
482
482
|
def declaration_to_xml(decl)
|
|
@@ -503,11 +503,11 @@ module Moxml
|
|
|
503
503
|
|
|
504
504
|
if should_include_decl
|
|
505
505
|
decl = effective_xml_declaration || node.xml_declaration
|
|
506
|
-
if decl
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
506
|
+
output << if decl
|
|
507
|
+
declaration_to_xml(decl)
|
|
508
|
+
else
|
|
509
|
+
'<?xml version="1.0" encoding="UTF-8"?>'
|
|
510
|
+
end
|
|
511
511
|
output << "\n"
|
|
512
512
|
end
|
|
513
513
|
|
data/lib/moxml/adapter/ox.rb
CHANGED
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
return if RUBY_ENGINE == "opal"
|
|
4
4
|
|
|
5
|
-
require_relative "base"
|
|
6
5
|
require "ox"
|
|
7
6
|
require "stringio"
|
|
8
|
-
require_relative "customized_ox"
|
|
9
|
-
require_relative "../sax/namespace_splitter"
|
|
10
7
|
|
|
11
8
|
# insert :parent methods to all Ox classes inherit the Node class
|
|
12
9
|
Ox::Node.attr_accessor :parent
|
|
@@ -20,14 +17,13 @@ module Moxml
|
|
|
20
17
|
|
|
21
18
|
def set_root(doc, element)
|
|
22
19
|
existing_root = root(doc)
|
|
20
|
+
element.parent = doc if element.is_a?(::Ox::Node)
|
|
23
21
|
if existing_root
|
|
24
22
|
# Replace the existing root element, preserving other children
|
|
25
|
-
element.parent = doc if element.is_a?(::Ox::Node)
|
|
26
23
|
idx = doc.nodes.index(existing_root)
|
|
27
24
|
doc.nodes[idx] = element
|
|
28
25
|
else
|
|
29
26
|
# No root yet, just append the element
|
|
30
|
-
element.parent = doc if element.is_a?(::Ox::Node)
|
|
31
27
|
doc << element
|
|
32
28
|
end
|
|
33
29
|
end
|
|
@@ -116,7 +112,7 @@ module Moxml
|
|
|
116
112
|
elsif system_id
|
|
117
113
|
"#{name} SYSTEM \"#{system_id}\""
|
|
118
114
|
else
|
|
119
|
-
|
|
115
|
+
name.to_s
|
|
120
116
|
end
|
|
121
117
|
::Ox::DocType.new(value)
|
|
122
118
|
end
|
|
@@ -272,7 +268,7 @@ module Moxml
|
|
|
272
268
|
# Ox doesn't set parent references during parsing.
|
|
273
269
|
# Set them here so parent/sibling navigation works.
|
|
274
270
|
result.each do |child|
|
|
275
|
-
child.parent = node if child.
|
|
271
|
+
child.parent = node if child.is_a?(::Ox::Element)
|
|
276
272
|
end
|
|
277
273
|
result
|
|
278
274
|
end
|
|
@@ -383,12 +379,15 @@ module Moxml
|
|
|
383
379
|
end
|
|
384
380
|
|
|
385
381
|
def add_child(element, child)
|
|
386
|
-
# Special handling for declarations on Ox documents
|
|
387
382
|
if element.is_a?(::Ox::Document) && child.is_a?(::Ox::Instruct) && child.target == "xml"
|
|
388
383
|
element.attributes ||= {}
|
|
389
384
|
element.attributes[:version] = child.attributes["version"] if child.attributes["version"]
|
|
390
385
|
element.attributes[:encoding] = child.attributes["encoding"] if child.attributes["encoding"]
|
|
391
386
|
element.attributes[:standalone] = child.attributes["standalone"] if child.attributes["standalone"]
|
|
387
|
+
attachments.set(element, :decl_explicit, {
|
|
388
|
+
encoding: child.attributes.key?("encoding") ? child.attributes["encoding"] : nil,
|
|
389
|
+
standalone: child.attributes.key?("standalone") ? child.attributes["standalone"] : nil,
|
|
390
|
+
})
|
|
392
391
|
return
|
|
393
392
|
end
|
|
394
393
|
|
|
@@ -481,8 +480,8 @@ module Moxml
|
|
|
481
480
|
end
|
|
482
481
|
|
|
483
482
|
def assign_parents(node, parent = nil)
|
|
484
|
-
node.parent = parent if node.
|
|
485
|
-
return unless node.
|
|
483
|
+
node.parent = parent if node.is_a?(::Ox::Element) && parent
|
|
484
|
+
return unless node.is_a?(::Ox::Element) || node.is_a?(::Ox::Document)
|
|
486
485
|
|
|
487
486
|
node.nodes&.each do |child|
|
|
488
487
|
assign_parents(child, node)
|
|
@@ -688,12 +687,26 @@ module Moxml
|
|
|
688
687
|
end
|
|
689
688
|
|
|
690
689
|
def has_declaration?(native_doc, _wrapper)
|
|
691
|
-
# Ox stores declaration in document attributes
|
|
692
690
|
native_doc[:version] || native_doc[:encoding] || native_doc[:standalone]
|
|
693
691
|
end
|
|
694
692
|
|
|
693
|
+
def remove_declaration(native_doc)
|
|
694
|
+
native_doc.attributes&.delete(:version)
|
|
695
|
+
native_doc.attributes&.delete(:encoding)
|
|
696
|
+
native_doc.attributes&.delete(:standalone)
|
|
697
|
+
attachments.delete(native_doc, :decl_explicit)
|
|
698
|
+
end
|
|
699
|
+
|
|
695
700
|
private
|
|
696
701
|
|
|
702
|
+
def resolve_decl_attr(node, attr, fallback)
|
|
703
|
+
if attachments.key?(node, :decl_explicit)
|
|
704
|
+
attachments.get(node, :decl_explicit)[attr]
|
|
705
|
+
else
|
|
706
|
+
node[attr] || fallback
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
|
|
697
710
|
def serialize_standard(node, options = {})
|
|
698
711
|
output = ""
|
|
699
712
|
if node.is_a?(::Ox::Document)
|
|
@@ -705,8 +718,8 @@ module Moxml
|
|
|
705
718
|
|
|
706
719
|
if should_include_decl
|
|
707
720
|
version = node[:version] || "1.0"
|
|
708
|
-
encoding =
|
|
709
|
-
standalone = node
|
|
721
|
+
encoding = resolve_decl_attr(node, :encoding, options[:encoding])
|
|
722
|
+
standalone = resolve_decl_attr(node, :standalone, nil)
|
|
710
723
|
|
|
711
724
|
decl = create_native_declaration(version, encoding, standalone)
|
|
712
725
|
output = ::Ox.dump(::Ox::Document.new << decl).strip
|
|
@@ -715,7 +728,7 @@ module Moxml
|
|
|
715
728
|
|
|
716
729
|
ox_options = {
|
|
717
730
|
indent: -1,
|
|
718
|
-
with_instructions:
|
|
731
|
+
with_instructions: false,
|
|
719
732
|
encoding: options[:encoding],
|
|
720
733
|
no_empty: options[:expand_empty],
|
|
721
734
|
}
|
|
@@ -767,8 +780,8 @@ module Moxml
|
|
|
767
780
|
end
|
|
768
781
|
if should_include_decl
|
|
769
782
|
version = node[:version] || "1.0"
|
|
770
|
-
encoding =
|
|
771
|
-
standalone = node
|
|
783
|
+
encoding = resolve_decl_attr(node, :encoding, options[:encoding])
|
|
784
|
+
standalone = resolve_decl_attr(node, :standalone, nil)
|
|
772
785
|
output << "<?xml version=\"#{version}\""
|
|
773
786
|
output << " encoding=\"#{encoding}\"" if encoding
|
|
774
787
|
output << " standalone=\"#{standalone}\"" if standalone
|
data/lib/moxml/adapter/rexml.rb
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "base"
|
|
4
3
|
require "rexml/document"
|
|
5
4
|
require "rexml/xpath"
|
|
6
5
|
require "set" unless RUBY_ENGINE == "opal"
|
|
7
6
|
require "stringio" if RUBY_ENGINE == "opal"
|
|
8
|
-
require_relative "customized_rexml"
|
|
9
|
-
require_relative "../sax/namespace_splitter"
|
|
10
7
|
|
|
11
8
|
module Moxml
|
|
12
9
|
module Adapter
|
|
@@ -173,7 +170,7 @@ module Moxml
|
|
|
173
170
|
end
|
|
174
171
|
|
|
175
172
|
def duplicate_node(node)
|
|
176
|
-
if node.
|
|
173
|
+
if node.is_a?(::REXML::Parent)
|
|
177
174
|
node.deep_clone
|
|
178
175
|
else
|
|
179
176
|
Marshal.load(Marshal.dump(node))
|
|
@@ -620,9 +617,7 @@ module Moxml
|
|
|
620
617
|
def has_declaration?(native_doc, wrapper)
|
|
621
618
|
xml_decl = attachments.get(native_doc, :xml_declaration)
|
|
622
619
|
if xml_decl.nil?
|
|
623
|
-
# Attachment key doesn't exist - check native doc or wrapper flag
|
|
624
620
|
if attachments.key?(native_doc, :xml_declaration)
|
|
625
|
-
# Explicitly set to nil (was removed)
|
|
626
621
|
false
|
|
627
622
|
else
|
|
628
623
|
wrapper.has_xml_declaration
|
|
@@ -632,6 +627,10 @@ module Moxml
|
|
|
632
627
|
end
|
|
633
628
|
end
|
|
634
629
|
|
|
630
|
+
def remove_declaration(native_doc)
|
|
631
|
+
attachments.set(native_doc, :xml_declaration, nil)
|
|
632
|
+
end
|
|
633
|
+
|
|
635
634
|
private
|
|
636
635
|
|
|
637
636
|
def write_with_formatter(node, output, indent = 2)
|
data/lib/moxml/adapter.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "adapter/base"
|
|
4
|
-
|
|
5
3
|
module Moxml
|
|
6
4
|
module Adapter
|
|
5
|
+
autoload :Base, "moxml/adapter/base"
|
|
6
|
+
autoload :CustomizedOga, "moxml/adapter/customized_oga"
|
|
7
|
+
autoload :CustomizedOx, "moxml/adapter/customized_ox"
|
|
8
|
+
autoload :CustomizedRexml, "moxml/adapter/customized_rexml"
|
|
9
|
+
autoload :CustomizedLibxml, "moxml/adapter/customized_libxml"
|
|
10
|
+
|
|
7
11
|
AVAILABLE_ADAPTERS = %i[nokogiri oga rexml ox headed_ox libxml].freeze
|
|
8
12
|
|
|
9
13
|
# Adapters that work under the Opal (JavaScript) runtime.
|
|
@@ -59,11 +63,15 @@ module Moxml
|
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
def require_adapter(name)
|
|
62
|
-
require
|
|
66
|
+
# Opal pre-loads all dependencies via the Rakefile; skip runtime require.
|
|
67
|
+
return if RUBY_ENGINE == "opal"
|
|
68
|
+
|
|
69
|
+
require "moxml/adapter/base"
|
|
70
|
+
require "moxml/adapter/#{name}"
|
|
63
71
|
rescue LoadError
|
|
64
72
|
begin
|
|
65
73
|
require name.to_s
|
|
66
|
-
require "
|
|
74
|
+
require "moxml/adapter/#{name}"
|
|
67
75
|
rescue LoadError => e
|
|
68
76
|
raise Moxml::AdapterError.new(
|
|
69
77
|
"Failed to load #{name} adapter",
|
data/lib/moxml/attribute.rb
CHANGED
|
@@ -21,6 +21,8 @@ module Moxml
|
|
|
21
21
|
adapter.restore_entities(val)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
alias content value
|
|
25
|
+
|
|
24
26
|
# Returns raw native value without entity marker restoration.
|
|
25
27
|
def raw_value
|
|
26
28
|
@native.value
|
|
@@ -46,11 +48,12 @@ module Moxml
|
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def element
|
|
49
|
-
adapter.attribute_element(@native)
|
|
51
|
+
native_elem = adapter.attribute_element(@native)
|
|
52
|
+
native_elem && Moxml::Node.wrap(native_elem, context)
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
def remove
|
|
53
|
-
adapter.remove_attribute(
|
|
56
|
+
adapter.remove_attribute(adapter.attribute_element(@native), name)
|
|
54
57
|
if @parent_node.is_a?(Moxml::Element)
|
|
55
58
|
@parent_node.invalidate_attribute_cache!
|
|
56
59
|
end
|
data/lib/moxml/config.rb
CHANGED
data/lib/moxml/context.rb
CHANGED
|
@@ -17,13 +17,12 @@ module Moxml
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def parse(xml, options = {})
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
xml_string = if xml.is_a?(String)
|
|
21
|
+
xml
|
|
22
|
+
else
|
|
22
23
|
xml.read.tap do
|
|
23
|
-
xml.rewind if xml.
|
|
24
|
+
xml.rewind if xml.is_a?(IO) || xml.is_a?(StringIO)
|
|
24
25
|
end
|
|
25
|
-
else
|
|
26
|
-
xml.to_s
|
|
27
26
|
end
|
|
28
27
|
has_declaration = xml_string.strip.start_with?("<?xml")
|
|
29
28
|
|
|
@@ -59,9 +58,6 @@ module Moxml
|
|
|
59
58
|
# end
|
|
60
59
|
#
|
|
61
60
|
def sax_parse(xml, handler = nil, &block)
|
|
62
|
-
# Load SAX module if not already loaded
|
|
63
|
-
require_relative "sax" unless defined?(Moxml::SAX)
|
|
64
|
-
|
|
65
61
|
# Create block handler if block given
|
|
66
62
|
handler ||= SAX::BlockHandler.new(&block) if block
|
|
67
63
|
|
|
@@ -75,6 +71,10 @@ module Moxml
|
|
|
75
71
|
config.adapter.sax_parse(xml, handler)
|
|
76
72
|
end
|
|
77
73
|
|
|
74
|
+
def build(&block)
|
|
75
|
+
Builder.new(self).build(&block)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
78
|
private
|
|
79
79
|
|
|
80
80
|
def build_entity_registry
|
data/lib/moxml/declaration.rb
CHANGED
|
@@ -34,13 +34,8 @@ module Moxml
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def remove
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
native_doc = adapter.document(@native)
|
|
40
|
-
if native_doc && adapter.respond_to?(:attachments)
|
|
41
|
-
adapter.attachments.set(native_doc, :has_declaration, false)
|
|
42
|
-
end
|
|
43
|
-
|
|
37
|
+
native_doc = @parent_node&.native
|
|
38
|
+
adapter.remove_declaration(native_doc) if native_doc
|
|
44
39
|
super
|
|
45
40
|
end
|
|
46
41
|
|