multisax 0.0.0.5 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +27 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +1 -3
- data/README.rdoc +8 -7
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/lib/multisax.rb +72 -34
- data/multisax.gemspec +3 -2
- data/spec/multisax_spec.rb +40 -7
- data/spec/spec_helper.rb +11 -0
- metadata +4 -3
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
= ChangeLog
|
2
|
+
|
3
|
+
== 0.0.1 (2013 Jul 8)
|
4
|
+
- Added ChangeLog.
|
5
|
+
- Added Ruby 1.8.7 support.
|
6
|
+
- Might work on lower version, but not guaranteed.
|
7
|
+
- JRuby etc's supports depend on "require successfulness".
|
8
|
+
- Nokogiri is supported up to 1.5.x on Ruby 1.8.x.
|
9
|
+
- MultiSAX::Sax.parse supports IO.
|
10
|
+
- rexmlsax2's stringio support is limited on Ruby 1.8.x. Be careful.
|
11
|
+
- Unless you directly specifies it, usually rexmlstream is selected.
|
12
|
+
- Added MultiSAX::Sax.parsefile().
|
13
|
+
|
14
|
+
== 0.0.0.5 (2013 Jun 21)
|
15
|
+
- Added a test case.
|
16
|
+
|
17
|
+
== 0.0.0.4 (2013 Jun 15)
|
18
|
+
- Provided rdoc.
|
19
|
+
|
20
|
+
== 0.0.0.3 (2013 Jun 14)
|
21
|
+
- Fixed @@parser getter.
|
22
|
+
|
23
|
+
== 0.0.0.2 (2013 Jun 14)
|
24
|
+
- Fixed Rakefile.
|
25
|
+
|
26
|
+
== 0.0.0.1 (2013 Jun 14)
|
27
|
+
- First release.
|
data/Gemfile
CHANGED
@@ -2,7 +2,11 @@ source "http://rubygems.org"
|
|
2
2
|
|
3
3
|
group :optional do
|
4
4
|
gem 'libxml-ruby', :require=>nil
|
5
|
-
|
5
|
+
if RUBY_VERSION<'1.9'
|
6
|
+
gem 'nokogiri', '~> 1.5.0', :require=>nil
|
7
|
+
else
|
8
|
+
gem 'nokogiri', :require=>nil
|
9
|
+
end
|
6
10
|
gem 'ox', :require=>nil
|
7
11
|
end
|
8
12
|
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
= multisax
|
2
2
|
|
3
|
+
== Install
|
4
|
+
* gem install multisax
|
5
|
+
* Optional XML libraries:
|
6
|
+
* gem install ox
|
7
|
+
* gem install libxml-ruby
|
8
|
+
* gem install nokogiri
|
9
|
+
|
10
|
+
== Usage
|
3
11
|
* Please check spec/multisax.spec as an example.
|
4
12
|
* Complex usage:
|
5
13
|
require 'multisax'
|
@@ -29,13 +37,7 @@
|
|
29
37
|
}.new)
|
30
38
|
listener.content.each{...}
|
31
39
|
|
32
|
-
* Optional XML libraries:
|
33
|
-
* gem install ox
|
34
|
-
* gem install libxml-ruby
|
35
|
-
* gem install nokogiri
|
36
|
-
|
37
40
|
== Contributing to multisax
|
38
|
-
|
39
41
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
40
42
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
41
43
|
* Fork the project.
|
@@ -45,6 +47,5 @@
|
|
45
47
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
46
48
|
|
47
49
|
== Copyright
|
48
|
-
|
49
50
|
Copyright (c) 2013 T. Yamada under Ruby License (2-clause BSDL or Artistic).
|
50
51
|
See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
@@ -45,7 +45,8 @@ Rake::RDocTask.new do |rdoc|
|
|
45
45
|
rdoc.rdoc_dir = 'rdoc'
|
46
46
|
rdoc.title = "multisax #{version}"
|
47
47
|
rdoc.main = 'README.rdoc'
|
48
|
-
rdoc.rdoc_files.include('README
|
49
|
-
rdoc.rdoc_files.include('LICENSE
|
48
|
+
rdoc.rdoc_files.include('README.*')
|
49
|
+
rdoc.rdoc_files.include('LICENSE.*')
|
50
|
+
rdoc.rdoc_files.include('CHANGELOG.*')
|
50
51
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
52
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.1
|
data/lib/multisax.rb
CHANGED
@@ -25,13 +25,18 @@ module MultiSAX
|
|
25
25
|
list.each{|e_module|
|
26
26
|
case e_module
|
27
27
|
when :ox
|
28
|
+
#next if RUBY_VERSION<'1.9'
|
28
29
|
begin
|
29
30
|
require 'ox'
|
30
31
|
require 'stringio' #this should be standard module.
|
31
32
|
rescue LoadError;next end
|
32
33
|
@@parser=e_module
|
33
34
|
methods=Ox::Sax.private_instance_methods(false)-Class.private_instance_methods(false)
|
34
|
-
methods
|
35
|
+
if methods[0].is_a?(String) #Hack for 1.8.x
|
36
|
+
methods-=['value','attr_value']
|
37
|
+
else
|
38
|
+
methods-=[:value,:attr_value]
|
39
|
+
end
|
35
40
|
@@saxmodule=Module.new{
|
36
41
|
methods.each{|e|define_method(e){|*a|}}
|
37
42
|
}
|
@@ -42,12 +47,18 @@ module MultiSAX
|
|
42
47
|
rescue LoadError;next end
|
43
48
|
@@parser=e_module;break
|
44
49
|
when :nokogiri
|
50
|
+
#nokogiri 1.5.x are supported on Ruby 1.8.7.
|
51
|
+
#next if RUBY_VERSION<'1.9'
|
45
52
|
begin
|
46
53
|
require 'nokogiri'
|
47
54
|
rescue LoadError;next end
|
48
55
|
@@parser=e_module
|
49
56
|
methods=Nokogiri::XML::SAX::Document.instance_methods(false)-Class.instance_methods(false)
|
50
|
-
methods
|
57
|
+
if methods[0].is_a?(String) #Hack for 1.8.x
|
58
|
+
methods-=['start_element_namespace','end_element_namespace']
|
59
|
+
else
|
60
|
+
methods-=[:start_element_namespace,:end_element_namespace]
|
61
|
+
end
|
51
62
|
@@saxmodule=Module.new{
|
52
63
|
methods.each{|e|define_method(e){|*a|}}
|
53
64
|
}
|
@@ -75,30 +86,19 @@ module MultiSAX
|
|
75
86
|
# Returns which module is actually chosen.
|
76
87
|
def self.parser() @@parser end
|
77
88
|
|
78
|
-
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
# The main parsing method.
|
83
|
-
# Listener can be Class.new{include MultiSAX::Callbacks}.new. Returns the listener after SAX is applied.
|
84
|
-
# If you have not called open(), this will call it using default value (all libraries).
|
85
|
-
# SAX's listeners are usually modified destructively.
|
86
|
-
# So instances shouldn't be provided.
|
87
|
-
def self.parse(body,listener)
|
88
|
-
#self.class.open if !@@parser
|
89
|
-
self.open if !@@parser
|
90
|
-
raise "Failed to open SAX library. REXML, which is a standard Ruby module, might be also corrupted." if !@@parser
|
91
|
-
@listener=listener
|
92
|
-
|
93
|
-
#Here comes method mapping.
|
89
|
+
private
|
90
|
+
#(private) Patches listener to accept library-specific APIs.
|
91
|
+
def self.method_mapping(listener)
|
92
|
+
#raise "MultiSAX::Sax open first" if !@@parser
|
94
93
|
case @@parser
|
95
94
|
when :ox
|
96
|
-
|
95
|
+
listener.instance_eval{
|
97
96
|
extend @@saxmodule
|
97
|
+
@saxwrapper_tag=nil
|
98
98
|
@saxwrapper_attr=[]
|
99
99
|
def start_element(tag)
|
100
100
|
# I hope provided Listener's sax_tag_start will NOT be used elsewhere.
|
101
|
-
alias :attrs_done :attrs_done_normal
|
101
|
+
#alias :attrs_done :attrs_done_normal
|
102
102
|
@saxwrapper_tag=tag
|
103
103
|
@saxwrapper_attr=[]
|
104
104
|
end
|
@@ -122,7 +122,10 @@ module MultiSAX
|
|
122
122
|
def attrs_done_normal
|
123
123
|
sax_tag_start(@saxwrapper_tag.to_s,@saxwrapper_attr)
|
124
124
|
end
|
125
|
-
alias :attrs_done :attrs_done_xmldecl
|
125
|
+
#alias :attrs_done :attrs_done_xmldecl
|
126
|
+
def attrs_done
|
127
|
+
@saxwrapper_tag ? attrs_done_normal : attrs_done_xmldecl
|
128
|
+
end
|
126
129
|
def end_element(tag) sax_tag_end(tag.to_s) end
|
127
130
|
alias :cdata :sax_cdata
|
128
131
|
alias :text :sax_text
|
@@ -132,7 +135,7 @@ module MultiSAX
|
|
132
135
|
alias :comment :sax_comment
|
133
136
|
}
|
134
137
|
when :libxml
|
135
|
-
|
138
|
+
listener.instance_eval{
|
136
139
|
extend LibXML::XML::SaxParser::Callbacks
|
137
140
|
alias :on_start_element :sax_tag_start
|
138
141
|
alias :on_end_element :sax_tag_end
|
@@ -142,7 +145,7 @@ module MultiSAX
|
|
142
145
|
#alias :xmldecl :sax_xmldecl
|
143
146
|
}
|
144
147
|
when :nokogiri
|
145
|
-
|
148
|
+
listener.instance_eval{
|
146
149
|
extend @@saxmodule
|
147
150
|
alias :start_element_namespace :sax_start_element_namespace
|
148
151
|
alias :start_element :sax_tag_start
|
@@ -154,7 +157,7 @@ module MultiSAX
|
|
154
157
|
alias :xmldecl :sax_xmldecl
|
155
158
|
}
|
156
159
|
when :rexmlstream
|
157
|
-
|
160
|
+
listener.instance_eval{
|
158
161
|
extend REXML::StreamListener
|
159
162
|
alias :tag_start :sax_tag_start
|
160
163
|
alias :tag_end :sax_tag_end
|
@@ -164,7 +167,7 @@ module MultiSAX
|
|
164
167
|
alias :xmldecl :sax_xmldecl
|
165
168
|
}
|
166
169
|
when :rexmlsax2
|
167
|
-
|
170
|
+
listener.instance_eval{
|
168
171
|
extend REXML::SAX2Listener
|
169
172
|
def start_element(uri,tag,qname,attrs) sax_tag_start(tag,attrs) end
|
170
173
|
def end_element(uri,tag,qname) sax_tag_end(tag) end
|
@@ -174,18 +177,53 @@ module MultiSAX
|
|
174
177
|
alias :xmldecl :sax_xmldecl
|
175
178
|
}
|
176
179
|
end
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
180
|
+
listener
|
181
|
+
end
|
182
|
+
|
183
|
+
public
|
184
|
+
# The main parsing method.
|
185
|
+
# Listener can be Class.new{include MultiSAX::Callbacks}.new. Returns the listener after SAX is applied.
|
186
|
+
# If you have not called open(), this will call it using default value (all libraries).
|
187
|
+
# From 0.0.1, source can be IO as well as String.
|
188
|
+
# SAX's listeners are usually modified destructively.
|
189
|
+
# So instances shouldn't be provided.
|
190
|
+
def self.parse(source,listener)
|
191
|
+
self.open if !@@parser
|
192
|
+
raise "Failed to open SAX library. REXML, which is a standard Ruby module, might be also corrupted." if !@@parser
|
193
|
+
@listener=listener
|
194
|
+
self.method_mapping(@listener)
|
195
|
+
if source.is_a?(String)
|
196
|
+
case @@parser
|
197
|
+
when :ox then Ox.sax_parse(@listener,StringIO.new(source),:convert_special=>true)
|
198
|
+
when :libxml then parser=LibXML::XML::SaxParser.string(source);parser.callbacks=@listener;parser.parse
|
199
|
+
when :nokogiri then parser=Nokogiri::XML::SAX::Parser.new(@listener);parser.parse(source)
|
200
|
+
when :rexmlstream then REXML::Parsers::StreamParser.new(source,@listener).parse
|
201
|
+
when :rexmlsax2 then parser=REXML::Parsers::SAX2Parser.new(source);parser.listen(@listener);parser.parse
|
202
|
+
end
|
203
|
+
else
|
204
|
+
case @@parser
|
205
|
+
when :ox then Ox.sax_parse(@listener,source,:convert_special=>true)
|
206
|
+
when :libxml then parser=LibXML::XML::SaxParser.io(source);parser.callbacks=@listener;parser.parse
|
207
|
+
when :nokogiri then parser=Nokogiri::XML::SAX::Parser.new(@listener);parser.parse(source)
|
208
|
+
when :rexmlstream then REXML::Parsers::StreamParser.new(source,@listener).parse
|
209
|
+
when :rexmlsax2 then parser=REXML::Parsers::SAX2Parser.new(source);parser.listen(@listener);parser.parse
|
210
|
+
end
|
186
211
|
end
|
187
212
|
@listener
|
188
213
|
end
|
214
|
+
|
215
|
+
# Parses file as XML. Error handling might be changed in the future.
|
216
|
+
def self.parsefile(filename,listener)
|
217
|
+
#begin
|
218
|
+
return nil unless FileTest::readable?(filename)
|
219
|
+
File.open(filename,'rb'){|f|
|
220
|
+
self.parse(f,listener)
|
221
|
+
}
|
222
|
+
#rescue
|
223
|
+
# return nil
|
224
|
+
#end
|
225
|
+
@listener
|
226
|
+
end
|
189
227
|
end
|
190
228
|
|
191
229
|
# MultiSAX callbacks.
|
data/multisax.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "multisax"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["cielavenir"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-07-08"
|
13
13
|
s.description = "Ruby Gem to handle multiple SAX libraries: ox/libxml/nokogiri/rexml"
|
14
14
|
s.email = "cielartisan@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".rspec",
|
22
|
+
"CHANGELOG.rdoc",
|
22
23
|
"Gemfile",
|
23
24
|
"Gemfile.lock",
|
24
25
|
"LICENSE.txt",
|
data/spec/multisax_spec.rb
CHANGED
@@ -25,39 +25,72 @@ input_xml=<<"EOM"
|
|
25
25
|
EOM
|
26
26
|
answer=['hello','sax','world','sax','hello']
|
27
27
|
|
28
|
-
describe "
|
29
|
-
it "unknown" do
|
28
|
+
describe "MultiSAX::Sax.parse (String)" do
|
29
|
+
it "fails on :unknown" do
|
30
30
|
MultiSAX::Sax.reset
|
31
31
|
MultiSAX::Sax.open(:unknown).should be_false
|
32
32
|
end
|
33
|
-
it "rexmlstream" do
|
33
|
+
it ":rexmlstream" do
|
34
34
|
MultiSAX::Sax.reset
|
35
35
|
MultiSAX::Sax.open(:rexmlstream)
|
36
36
|
MultiSAX::Sax.parser.should eq :rexmlstream
|
37
37
|
MultiSAX::Sax.parse(input_xml,MultiSAXTester.new).result.should eq answer
|
38
38
|
end
|
39
|
-
it "rexmlsax2" do
|
39
|
+
it ":rexmlsax2" do
|
40
40
|
MultiSAX::Sax.reset
|
41
41
|
MultiSAX::Sax.open(:rexmlsax2)
|
42
42
|
MultiSAX::Sax.parser.should eq :rexmlsax2
|
43
43
|
MultiSAX::Sax.parse(input_xml,MultiSAXTester.new).result.should eq answer
|
44
44
|
end
|
45
|
-
it "ox" do
|
45
|
+
it ":ox" do
|
46
46
|
MultiSAX::Sax.reset
|
47
47
|
MultiSAX::Sax.open(:ox)
|
48
48
|
MultiSAX::Sax.parser.should eq :ox
|
49
49
|
MultiSAX::Sax.parse(input_xml,MultiSAXTester.new).result.should eq answer
|
50
50
|
end
|
51
|
-
it "libxml" do
|
51
|
+
it ":libxml" do
|
52
52
|
MultiSAX::Sax.reset
|
53
53
|
MultiSAX::Sax.open(:libxml)
|
54
54
|
MultiSAX::Sax.parser.should eq :libxml
|
55
55
|
MultiSAX::Sax.parse(input_xml,MultiSAXTester.new).result.should eq answer
|
56
56
|
end
|
57
|
-
it "nokogiri" do
|
57
|
+
it ":nokogiri" do
|
58
58
|
MultiSAX::Sax.reset
|
59
59
|
MultiSAX::Sax.open(:nokogiri)
|
60
60
|
MultiSAX::Sax.parser.should eq :nokogiri
|
61
61
|
MultiSAX::Sax.parse(input_xml,MultiSAXTester.new).result.should eq answer
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
describe "MultiSAX::Sax.parse (IO)" do
|
66
|
+
it ":rexmlstream" do
|
67
|
+
MultiSAX::Sax.reset
|
68
|
+
MultiSAX::Sax.open(:rexmlstream)
|
69
|
+
MultiSAX::Sax.parser.should eq :rexmlstream
|
70
|
+
MultiSAX::Sax.parse(StringIO.new(input_xml),MultiSAXTester.new).result.should eq answer
|
71
|
+
end
|
72
|
+
it ":rexmlsax2" do
|
73
|
+
MultiSAX::Sax.reset
|
74
|
+
MultiSAX::Sax.open(:rexmlsax2)
|
75
|
+
MultiSAX::Sax.parser.should eq :rexmlsax2
|
76
|
+
MultiSAX::Sax.parse(StringIO.new(input_xml),MultiSAXTester.new).result.should eq answer
|
77
|
+
end
|
78
|
+
it ":ox" do
|
79
|
+
MultiSAX::Sax.reset
|
80
|
+
MultiSAX::Sax.open(:ox)
|
81
|
+
MultiSAX::Sax.parser.should eq :ox
|
82
|
+
MultiSAX::Sax.parse(StringIO.new(input_xml),MultiSAXTester.new).result.should eq answer
|
83
|
+
end
|
84
|
+
it ":libxml" do
|
85
|
+
MultiSAX::Sax.reset
|
86
|
+
MultiSAX::Sax.open(:libxml)
|
87
|
+
MultiSAX::Sax.parser.should eq :libxml
|
88
|
+
MultiSAX::Sax.parse(StringIO.new(input_xml),MultiSAXTester.new).result.should eq answer
|
89
|
+
end
|
90
|
+
it ":nokogiri" do
|
91
|
+
MultiSAX::Sax.reset
|
92
|
+
MultiSAX::Sax.open(:nokogiri)
|
93
|
+
MultiSAX::Sax.parser.should eq :nokogiri
|
94
|
+
MultiSAX::Sax.parse(StringIO.new(input_xml),MultiSAXTester.new).result.should eq answer
|
95
|
+
end
|
96
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rspec'
|
4
|
+
require 'stringio'
|
4
5
|
require 'multisax'
|
5
6
|
|
7
|
+
if RUBY_VERSION<'1.9' #gee, StringIO needs to be hacked.
|
8
|
+
class StringIO
|
9
|
+
def stat
|
10
|
+
Class.new{
|
11
|
+
def pipe?() return false end
|
12
|
+
}.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
# Requires supporting files with custom matchers and macros, etc,
|
7
18
|
# in ./support/ and its subdirectories.
|
8
19
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multisax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -85,6 +85,7 @@ extra_rdoc_files:
|
|
85
85
|
files:
|
86
86
|
- .document
|
87
87
|
- .rspec
|
88
|
+
- CHANGELOG.rdoc
|
88
89
|
- Gemfile
|
89
90
|
- Gemfile.lock
|
90
91
|
- LICENSE.txt
|
@@ -110,7 +111,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
111
|
version: '0'
|
111
112
|
segments:
|
112
113
|
- 0
|
113
|
-
hash:
|
114
|
+
hash: 3842720625323194338
|
114
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
116
|
none: false
|
116
117
|
requirements:
|