rxerces 0.1.0 → 0.3.0
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
- checksums.yaml.gz.sig +4 -0
- data/CHANGES.md +21 -0
- data/Gemfile +7 -0
- data/README.md +6 -2
- data/Rakefile +43 -0
- data/certs/djberg96_pub.pem +26 -0
- data/examples/basic_usage.rb +75 -0
- data/examples/schema_example.rb +107 -0
- data/examples/simple_example.rb +34 -0
- data/examples/xpath_example.rb +108 -0
- data/ext/rxerces/rxerces.cpp +623 -1
- data/lib/rxerces/nokogiri.rb +34 -0
- data/lib/rxerces/version.rb +1 -1
- data/lib/rxerces.rb +0 -31
- data/rxerces.gemspec +33 -0
- data/spec/document_spec.rb +101 -0
- data/spec/element_spec.rb +25 -0
- data/spec/node_spec.rb +472 -0
- data/spec/nodeset_spec.rb +92 -0
- data/spec/nokogiri_compatibility_spec.rb +167 -0
- data/spec/rxerces_shared.rb +10 -0
- data/spec/rxerces_spec.rb +23 -0
- data/spec/schema_spec.rb +76 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/xpath_spec.rb +164 -0
- data.tar.gz.sig +0 -0
- metadata +71 -9
- metadata.gz.sig +2 -0
- data/lib/rxerces/rxerces.bundle +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'rxerces'
|
|
2
|
+
|
|
3
|
+
# Nokogiri compatibility module
|
|
4
|
+
# Provides drop-in replacement for Nokogiri XML parsing using RXerces
|
|
5
|
+
module Nokogiri
|
|
6
|
+
# Nokogiri-compatible XML module
|
|
7
|
+
module XML
|
|
8
|
+
# Parse XML from a string - delegates to RXerces
|
|
9
|
+
# @param string [String] XML string to parse
|
|
10
|
+
# @return [RXerces::XML::Document] parsed document
|
|
11
|
+
def self.parse(string)
|
|
12
|
+
RXerces::XML::Document.parse(string)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Alias Document class for compatibility
|
|
16
|
+
Document = RXerces::XML::Document
|
|
17
|
+
Node = RXerces::XML::Node
|
|
18
|
+
Element = RXerces::XML::Element
|
|
19
|
+
Text = RXerces::XML::Text
|
|
20
|
+
NodeSet = RXerces::XML::NodeSet
|
|
21
|
+
Schema = RXerces::XML::Schema
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Top-level parse method for compatibility
|
|
25
|
+
# @param string [String] XML string to parse
|
|
26
|
+
# @return [RXerces::XML::Document] parsed document
|
|
27
|
+
def self.XML(string)
|
|
28
|
+
RXerces::XML::Document.parse(string)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
alias_method :parse, :XML
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/rxerces/version.rb
CHANGED
data/lib/rxerces.rb
CHANGED
|
@@ -15,34 +15,3 @@ module RXerces
|
|
|
15
15
|
alias_method :parse, :XML
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
|
-
|
|
19
|
-
# Nokogiri compatibility module
|
|
20
|
-
module Nokogiri
|
|
21
|
-
# Nokogiri-compatible XML module
|
|
22
|
-
module XML
|
|
23
|
-
# Parse XML from a string - delegates to RXerces
|
|
24
|
-
# @param string [String] XML string to parse
|
|
25
|
-
# @return [RXerces::XML::Document] parsed document
|
|
26
|
-
def self.parse(string)
|
|
27
|
-
RXerces::XML::Document.parse(string)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Alias Document class for compatibility
|
|
31
|
-
Document = RXerces::XML::Document
|
|
32
|
-
Node = RXerces::XML::Node
|
|
33
|
-
Element = RXerces::XML::Element
|
|
34
|
-
Text = RXerces::XML::Text
|
|
35
|
-
NodeSet = RXerces::XML::NodeSet
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Top-level parse method for compatibility
|
|
39
|
-
# @param string [String] XML string to parse
|
|
40
|
-
# @return [RXerces::XML::Document] parsed document
|
|
41
|
-
def self.XML(string)
|
|
42
|
-
RXerces::XML::Document.parse(string)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
class << self
|
|
46
|
-
alias_method :parse, :XML
|
|
47
|
-
end
|
|
48
|
-
end
|
data/rxerces.gemspec
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Gem::Specification.new do |spec|
|
|
2
|
+
spec.name = "rxerces"
|
|
3
|
+
spec.version = "0.3.0"
|
|
4
|
+
spec.author = "Daniel J. Berger"
|
|
5
|
+
spec.email = "djberg96@gmail.com"
|
|
6
|
+
spec.cert_chain = ["certs/djberg96_pub.pem"]
|
|
7
|
+
spec.homepage = "http://github.com/djberg96/rxerces"
|
|
8
|
+
spec.summary = "Nokogiri-compatible XML library using Xerces-C"
|
|
9
|
+
spec.license = "MIT"
|
|
10
|
+
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
|
11
|
+
spec.test_files = Dir['spec/*_spec.rb']
|
|
12
|
+
spec.extensions = ["ext/rxerces/extconf.rb"]
|
|
13
|
+
|
|
14
|
+
spec.required_ruby_version = ">= 2.7.0"
|
|
15
|
+
|
|
16
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
17
|
+
spec.add_development_dependency "rake-compiler", "~> 1.2"
|
|
18
|
+
spec.add_development_dependency "rspec", "~> 3.12"
|
|
19
|
+
|
|
20
|
+
spec.description = "A Ruby XML library with Nokogiri-compatible API, powered by Xerces-C instead of libxml2"
|
|
21
|
+
|
|
22
|
+
spec.metadata = {
|
|
23
|
+
'homepage_uri' => 'https://github.com/djberg96/rxerces',
|
|
24
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/rxerces/issues',
|
|
25
|
+
'changelog_uri' => 'https://github.com/djberg96/rxerces/blob/main/CHANGES.md',
|
|
26
|
+
'documentation_uri' => 'https://github.com/djberg96/rxerces/wiki',
|
|
27
|
+
'source_code_uri' => 'https://github.com/djberg96/rxerces',
|
|
28
|
+
'wiki_uri' => 'https://github.com/djberg96/rxerces/wiki',
|
|
29
|
+
'rubygems_mfa_required' => 'true',
|
|
30
|
+
'github_repo' => 'https://github.com/djberg96/rxerces',
|
|
31
|
+
'funding_uri' => 'https://github.com/sponsors/djberg96'
|
|
32
|
+
}
|
|
33
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RXerces::XML::Document do
|
|
4
|
+
let(:simple_xml) { '<root><child>Hello</child></root>' }
|
|
5
|
+
let(:complex_xml) do
|
|
6
|
+
<<-XML
|
|
7
|
+
<root>
|
|
8
|
+
<person id="1" name="Alice">
|
|
9
|
+
<age>30</age>
|
|
10
|
+
<city>New York</city>
|
|
11
|
+
</person>
|
|
12
|
+
<person id="2" name="Bob">
|
|
13
|
+
<age>25</age>
|
|
14
|
+
<city>London</city>
|
|
15
|
+
</person>
|
|
16
|
+
</root>
|
|
17
|
+
XML
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe ".parse" do
|
|
21
|
+
it "parses simple XML" do
|
|
22
|
+
doc = RXerces::XML::Document.parse(simple_xml)
|
|
23
|
+
expect(doc).to be_a(RXerces::XML::Document)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "parses complex XML" do
|
|
27
|
+
doc = RXerces::XML::Document.parse(complex_xml)
|
|
28
|
+
expect(doc).to be_a(RXerces::XML::Document)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#root" do
|
|
33
|
+
it "returns the root element" do
|
|
34
|
+
doc = RXerces::XML::Document.parse(simple_xml)
|
|
35
|
+
root = doc.root
|
|
36
|
+
expect(root).to be_a(RXerces::XML::Element)
|
|
37
|
+
expect(root.name).to eq('root')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#to_s" do
|
|
42
|
+
it "serializes document to string" do
|
|
43
|
+
doc = RXerces::XML::Document.parse(simple_xml)
|
|
44
|
+
xml_string = doc.to_s
|
|
45
|
+
expect(xml_string).to be_a(String)
|
|
46
|
+
expect(xml_string).to include('<root>')
|
|
47
|
+
expect(xml_string).to include('<child>')
|
|
48
|
+
expect(xml_string).to include('Hello')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#to_xml" do
|
|
53
|
+
it "is an alias for to_s" do
|
|
54
|
+
doc = RXerces::XML::Document.parse(simple_xml)
|
|
55
|
+
expect(doc.to_xml).to eq(doc.to_s)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "#xpath" do
|
|
60
|
+
it "returns a NodeSet" do
|
|
61
|
+
doc = RXerces::XML::Document.parse(simple_xml)
|
|
62
|
+
result = doc.xpath('//child')
|
|
63
|
+
expect(result).to be_a(RXerces::XML::NodeSet)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#create_element" do
|
|
68
|
+
let(:doc) { RXerces::XML::Document.parse(simple_xml) }
|
|
69
|
+
|
|
70
|
+
it "creates a new element with the specified name" do
|
|
71
|
+
element = doc.create_element('book')
|
|
72
|
+
expect(element).to be_a(RXerces::XML::Element)
|
|
73
|
+
expect(element.name).to eq('book')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "creates an element that can have attributes set" do
|
|
77
|
+
element = doc.create_element('book')
|
|
78
|
+
attributes = element.attributes
|
|
79
|
+
expect(attributes).to be_a(Hash)
|
|
80
|
+
expect(attributes).to be_empty
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "creates an element that can have children added" do
|
|
84
|
+
element = doc.create_element('book')
|
|
85
|
+
element.add_child('Test Content')
|
|
86
|
+
expect(element.text).to eq('Test Content')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "creates an element that can be added to the document" do
|
|
90
|
+
root = doc.root
|
|
91
|
+
new_element = doc.create_element('new_child')
|
|
92
|
+
new_element.add_child('New content')
|
|
93
|
+
root.add_child(new_element)
|
|
94
|
+
|
|
95
|
+
# Verify the new element is in the document
|
|
96
|
+
result = doc.xpath('//new_child')
|
|
97
|
+
expect(result.length).to eq(1)
|
|
98
|
+
expect(result.first.text).to eq('New content')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RXerces::XML::Element do
|
|
4
|
+
let(:xml) { '<root><child id="1">Text</child></root>' }
|
|
5
|
+
let(:doc) { RXerces::XML::Document.parse(xml) }
|
|
6
|
+
let(:element) { doc.root }
|
|
7
|
+
|
|
8
|
+
it "is a subclass of Node" do
|
|
9
|
+
expect(element).to be_a(RXerces::XML::Node)
|
|
10
|
+
expect(element).to be_a(RXerces::XML::Element)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "has a name" do
|
|
14
|
+
expect(element.name).to eq('root')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "can have attributes" do
|
|
18
|
+
child = element.children.find { |n| n.is_a?(RXerces::XML::Element) }
|
|
19
|
+
expect(child['id']).to eq('1')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "can have children" do
|
|
23
|
+
expect(element.children).not_to be_empty
|
|
24
|
+
end
|
|
25
|
+
end
|