axml 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +34 -38
- data/Rakefile +19 -61
- data/lib/axml.rb +30 -367
- data/lib/axml/autoload.rb +106 -0
- data/lib/axml/el.rb +208 -0
- data/lib/axml/libxml.rb +110 -0
- data/lib/axml/traverse.rb +15 -0
- data/lib/axml/xmlparser.rb +114 -0
- data/spec/axml/autoload_spec.rb +18 -0
- data/spec/axml/libxml_spec.rb +13 -0
- data/spec/axml/xmlparser_spec.rb +16 -0
- data/spec/axml_spec.rb +299 -0
- metadata +18 -9
data/README
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
AXML
|
2
2
|
====
|
3
3
|
|
4
|
-
AXML - Provides a simple DOM for working with
|
5
|
-
|
6
|
-
|
4
|
+
AXML - Provides a simple, minimalistic DOM for working with data stored in an
|
5
|
+
XML document. The API is very similar to LibXML, differing slightly in the
|
6
|
+
handling of text nodes. It is designed with very large documents in mind: nodes are represented in memory efficient Struct objects and it works with either XMLParser or LibXML!
|
7
7
|
|
8
|
-
'AXML'
|
9
|
-
programmer towards XML or its myriad parsers. AXML
|
10
|
-
|
8
|
+
'AXML' literally translates into 'ax XML' which succinctly describes the
|
9
|
+
occasional feeling of a programmer towards XML or its myriad parsers. AXML
|
10
|
+
won't solve all your XML woes, but it does make working with XML much less
|
11
|
+
painful.
|
11
12
|
|
12
13
|
Features
|
13
14
|
--------
|
14
15
|
|
15
|
-
* *fast*:
|
16
|
-
* *lean*: as in 'lines of code'
|
16
|
+
* *fast*: runs on either XMLParser or LibXML
|
17
|
+
* *lean*: as in 'lines of code' and as in 'memory consumption' (nodes implemented as Struct, children in Array)
|
17
18
|
* *easy to extend*: code your Grandmother could read and understand (if she reads ruby)
|
18
|
-
*
|
19
|
-
|
19
|
+
* PLOS: implements a useful subset of libxml methods for near drop in replacement.
|
20
20
|
|
21
21
|
Examples
|
22
22
|
--------
|
23
23
|
|
24
|
-
require 'axml'
|
25
|
-
# Windows: already in one-click-installer
|
26
|
-
# Ubuntu: sudo apt-get install libxml-parser-ruby1.8
|
27
|
-
# Cygwin: see http://mspire.rubyforge.org/tutorial/cygwin_mspire.html
|
24
|
+
require 'axml'
|
28
25
|
|
29
26
|
# a little example xml string to use
|
30
27
|
string_or_io = "
|
@@ -39,18 +36,24 @@ Examples
|
|
39
36
|
</n1>
|
40
37
|
"
|
41
38
|
|
42
|
-
### Read a string or
|
39
|
+
### Read a string, io, or file
|
43
40
|
|
44
41
|
n1_node = AXML.parse(string_or_io)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
n1_node = AXML.parse_file('path/to/file')
|
42
|
+
# --or--
|
43
|
+
n1_node = AXML.parse('path/to/file')
|
49
44
|
|
50
45
|
### Access children
|
51
46
|
|
52
47
|
n1_node.children # -> [array]
|
53
|
-
n1_node.each {|child| # do something with child }
|
48
|
+
n1_node.each {|child| # do something with each child }
|
49
|
+
|
50
|
+
### Traverse the whole tree structure
|
51
|
+
|
52
|
+
n1_node.traverse do |node|
|
53
|
+
# pre traversal
|
54
|
+
end
|
55
|
+
|
56
|
+
n1_node.traverse(:post) {|node| # post traversal }
|
54
57
|
|
55
58
|
### Get attributes and text
|
56
59
|
|
@@ -59,7 +62,7 @@ Examples
|
|
59
62
|
n3_node.text # -> 'words here'
|
60
63
|
n3_node.content # -> [same]
|
61
64
|
|
62
|
-
###
|
65
|
+
### Navigate nodes
|
63
66
|
|
64
67
|
n2_node = n1_node.child
|
65
68
|
the_other_n2_node = n2_node.next
|
@@ -71,26 +74,12 @@ Examples
|
|
71
74
|
n3_node = n1_node.find_first('descendant::n3')
|
72
75
|
other_n3_node = n3_node.find_first('following-sibling::n3')
|
73
76
|
n1_node.find_first('child::n3') # -> nil
|
77
|
+
# also callable as find_first_child and find_first_descendant
|
74
78
|
|
75
79
|
# find (returns an array)
|
76
|
-
n1_node.find('descendant::n3') # -> [array of all 3 <n3> nodes]
|
77
80
|
n1_node.find('child::n2') # -> [array of 2 <n2> nodes]
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
This is all it takes to get all of the above code to work under libxml:
|
82
|
-
|
83
|
-
require 'xml/libxml' # instead of: require 'axml'
|
84
|
-
|
85
|
-
# A file
|
86
|
-
REPLACE: n1_node = AXML.parse_file(file)
|
87
|
-
WITH: n1_node = XML::Document.file(file).root # note the .root call on the end!
|
88
|
-
|
89
|
-
# A string
|
90
|
-
REPLACE: n1_node = AXML.parse(string)
|
91
|
-
WITH: n1_node = XML::Parser.string(string).parse.root # note the .root call on the end!
|
92
|
-
|
93
|
-
Wallah! All the above method calls work under libxml
|
81
|
+
n1_node.find('descendant::n3') # -> [array of all 3 <n3> nodes]
|
82
|
+
# also callable as find_child and find_descendant
|
94
83
|
|
95
84
|
|
96
85
|
See `specs/axml_spec.rb` for more examples and functionality
|
@@ -107,3 +96,10 @@ Installation
|
|
107
96
|
------------
|
108
97
|
|
109
98
|
gem install axml
|
99
|
+
|
100
|
+
See Also
|
101
|
+
--------
|
102
|
+
|
103
|
+
If you are parsing HTML or complex word processing documents this is not the parser for you. Try something like hpricot or LibXML.
|
104
|
+
|
105
|
+
|
data/Rakefile
CHANGED
@@ -2,9 +2,9 @@ require 'rake'
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
require 'rake/gempackagetask'
|
5
|
+
require 'rake/testtask'
|
5
6
|
require 'rake/clean'
|
6
7
|
require 'fileutils'
|
7
|
-
#require 'spec/rake/spectask'
|
8
8
|
require 'email_encrypt'
|
9
9
|
|
10
10
|
###############################################
|
@@ -59,7 +59,7 @@ task :html_docs do
|
|
59
59
|
|
60
60
|
# add contact info:
|
61
61
|
index.puts '<h2>Contact</h2>'
|
62
|
-
index.puts '
|
62
|
+
index.puts 'jtprince@gmail.com'.email_encrypt
|
63
63
|
|
64
64
|
index.puts '</body></html>'
|
65
65
|
end
|
@@ -75,64 +75,20 @@ end
|
|
75
75
|
# TESTS
|
76
76
|
###############################################
|
77
77
|
|
78
|
-
|
79
|
-
task :
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
78
|
+
desc 'Default: Run specs.'
|
79
|
+
task :default => :spec
|
80
|
+
|
81
|
+
desc 'Run specs.'
|
82
|
+
Rake::TestTask.new(:spec) do |t|
|
83
|
+
t.verbose = true
|
84
|
+
t.warning = true
|
85
|
+
ENV['RUBYOPT'] = 'rubygems'
|
86
|
+
ENV['TEST'] = ENV['SPEC'] if ENV['SPEC']
|
87
|
+
t.libs = ['lib']
|
88
|
+
t.test_files = Dir.glob( File.join('spec', ENV['pattern'] || '**/*_spec.rb') )
|
89
|
+
t.options = "-v"
|
89
90
|
end
|
90
91
|
|
91
|
-
#namespace :spec do
|
92
|
-
# task :autotest do
|
93
|
-
# require './specs/rspec_autotest'
|
94
|
-
# RspecAutotest.run
|
95
|
-
# end
|
96
|
-
#end
|
97
|
-
|
98
|
-
#desc "Run specs"
|
99
|
-
#Spec::Rake::SpecTask.new('spec') do |t|
|
100
|
-
# Rake::Task[:ensure_gem_is_uninstalled].invoke
|
101
|
-
# t.libs = ['lib']
|
102
|
-
# t.spec_files = FileList['specs/**/*_spec.rb']
|
103
|
-
#end
|
104
|
-
|
105
|
-
#desc "Run specs and output specdoc"
|
106
|
-
#Spec::Rake::SpecTask.new('specl') do |t|
|
107
|
-
# Rake::Task[:ensure_gem_is_uninstalled].invoke
|
108
|
-
# t.spec_files = FileList['specs/**/*_spec.rb']
|
109
|
-
# t.libs = ['lib']
|
110
|
-
# t.spec_opts = ['--format', 'specdoc' ]
|
111
|
-
#end
|
112
|
-
|
113
|
-
#desc "Run all specs with RCov"
|
114
|
-
#Spec::Rake::SpecTask.new('rcov') do |t|
|
115
|
-
# Rake::Task[:ensure_gem_is_uninstalled].invoke
|
116
|
-
# t.spec_files = FileList['specs/**/*_spec.rb']
|
117
|
-
# t.rcov = true
|
118
|
-
# t.libs = ['lib']
|
119
|
-
# t.rcov_opts = ['--exclude', 'specs']
|
120
|
-
#end
|
121
|
-
|
122
|
-
#task :spec do
|
123
|
-
# uninstall_gem
|
124
|
-
# # files that match a key word
|
125
|
-
# files_to_run = ENV['SPEC'] || FileList['specs/**/*_spec.rb']
|
126
|
-
# if ENV['SPECM']
|
127
|
-
# files_to_run = files_to_run.select do |file|
|
128
|
-
# file.include?(ENV['SPECM'])
|
129
|
-
# end
|
130
|
-
# end
|
131
|
-
# files_to_run.each do |spc|
|
132
|
-
# system "ruby -I lib -S spec #{spc} --format specdoc"
|
133
|
-
# end
|
134
|
-
#end
|
135
|
-
|
136
92
|
###############################################
|
137
93
|
# PACKAGE / INSTALL / UNINSTALL
|
138
94
|
###############################################
|
@@ -191,9 +147,11 @@ gemspec = Gem::Specification.new do |t|
|
|
191
147
|
t.platform = Gem::Platform::RUBY
|
192
148
|
t.name = NAME
|
193
149
|
t.version = IO.readlines(changelog).grep(/##.*version/).pop.split(/\s+/).last.chomp
|
150
|
+
t.homepage = 'http://axml.rubyforge.org/'
|
151
|
+
t.rubyforge_project = 'axml'
|
194
152
|
t.summary = summary
|
195
153
|
t.date = "#{tm.year}-#{tm.month}-#{tm.day}"
|
196
|
-
t.email = "
|
154
|
+
t.email = "jtprince@gmail.com"
|
197
155
|
t.description = description
|
198
156
|
t.has_rdoc = true
|
199
157
|
t.authors = ["John Prince"]
|
@@ -201,8 +159,8 @@ gemspec = Gem::Specification.new do |t|
|
|
201
159
|
t.rdoc_options = rdoc_options
|
202
160
|
t.extra_rdoc_files = rdoc_extra_includes
|
203
161
|
t.executables = FL["bin/*"].map {|file| File.basename(file) }
|
204
|
-
t.requirements << 'xmlparser
|
205
|
-
t.test_files = FL["
|
162
|
+
t.requirements << 'xmlparser or libxml'
|
163
|
+
t.test_files = FL["spec/**/*_spec.rb"]
|
206
164
|
end
|
207
165
|
|
208
166
|
desc "Create packages."
|
data/lib/axml.rb
CHANGED
@@ -1,376 +1,39 @@
|
|
1
|
-
require 'xmlparser'
|
2
1
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# :
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
if ti.is_a?(Array)
|
27
|
-
ti.first.to_s
|
28
|
-
else
|
29
|
-
ti.to_s
|
30
|
-
end
|
31
|
-
parser.set_single_text_indices(ti)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
parser.parse(stream)
|
35
|
-
parser.root
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
AXML::El = Struct.new(:parent, :name, :attrs, :text, :children, :array_index)
|
41
|
-
|
42
|
-
class AXML::El
|
43
|
-
include Enumerable
|
44
|
-
|
45
|
-
# use AXML::El::Indent.replace to swap without warning
|
46
|
-
# ["", " ", " ", " ", " ", " ", ... ]
|
47
|
-
Indent = ' '
|
48
|
-
# use AXML::El::Indentation.replace to replace w/o warning
|
49
|
-
Indentation = (0...30).to_a.map {|num| Indent*num }
|
50
|
-
|
51
|
-
# current depth
|
52
|
-
@@depth = 0
|
53
|
-
|
54
|
-
alias_method :content, :text
|
55
|
-
alias_method :content=, :text=
|
56
|
-
alias_method :kids, :children
|
57
|
-
alias_method :kids=, :children=
|
58
|
-
|
59
|
-
def [](attribute_string)
|
60
|
-
attrs[attribute_string]
|
61
|
-
end
|
62
|
-
|
63
|
-
def []=(attribute_string, value)
|
64
|
-
attrs[attribute_string] = value
|
65
|
-
end
|
66
|
-
|
67
|
-
# has text?
|
68
|
-
def text?
|
69
|
-
!!text
|
70
|
-
end
|
71
|
-
|
72
|
-
def children?
|
73
|
-
children.size > 0
|
74
|
-
end
|
75
|
-
alias_method :child?, :children?
|
76
|
-
|
77
|
-
# full traversal from the initial node
|
78
|
-
def traverse(type=:pre, &block)
|
79
|
-
if type == :pre
|
80
|
-
block.call(self)
|
81
|
-
end
|
82
|
-
children.each do |child|
|
83
|
-
child.traverse(type, &block)
|
84
|
-
end
|
85
|
-
if type == :post
|
86
|
-
block.call(self)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def each(&block)
|
91
|
-
children.each do |child|
|
92
|
-
block.call(child)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# drops the current element from the list of its parents children
|
97
|
-
def drop
|
98
|
-
parent.children.delete(self)
|
99
|
-
end
|
100
|
-
|
101
|
-
def drop_child(node)
|
102
|
-
found_it = false
|
103
|
-
found_index = nil
|
104
|
-
children.each_with_index do |v,i|
|
105
|
-
if found_it
|
106
|
-
v.array_index = i - 1
|
107
|
-
end
|
108
|
-
if v.object_id == node.object_id
|
109
|
-
found_index = i
|
110
|
-
found_it = true
|
111
|
-
end
|
112
|
-
end
|
113
|
-
children.delete_at(found_index) if found_index
|
114
|
-
end
|
115
|
-
|
116
|
-
def tabs
|
117
|
-
Indentation[@@depth]
|
118
|
-
end
|
119
|
-
|
120
|
-
EscapeCharsRe = /['"&><]/
|
121
|
-
|
122
|
-
# returns data escaped if necessary
|
123
|
-
def escape(data)
|
124
|
-
# modified slightly from xmlsimple.rb
|
125
|
-
return data if !data.is_a?(String) || data.nil? || data == ''
|
126
|
-
result = data.dup
|
127
|
-
if EscapeCharsRe.match(data)
|
128
|
-
result.gsub!('&', '&')
|
129
|
-
result.gsub!('<', '<')
|
130
|
-
result.gsub!('>', '>')
|
131
|
-
result.gsub!('"', '"')
|
132
|
-
result.gsub!("'", ''')
|
133
|
-
end
|
134
|
-
result
|
135
|
-
end
|
136
|
-
|
137
|
-
def to_s
|
138
|
-
attstring = ""
|
139
|
-
if attrs.size > 0
|
140
|
-
attstring = " " + attrs.collect { |k,v| "#{k}=\"#{escape(v)}\"" }.join(" ")
|
141
|
-
end
|
142
|
-
string = "#{tabs}<#{name}#{attstring}"
|
143
|
-
if children.size > 0
|
144
|
-
string << ">"
|
145
|
-
if text?
|
146
|
-
string << escape(text)
|
147
|
-
end
|
148
|
-
string << "\n"
|
149
|
-
@@depth += 1
|
150
|
-
string << children.collect {|child| child.to_s }.join("")
|
151
|
-
@@depth -= 1
|
152
|
-
string << "#{tabs}</#{name}>\n"
|
153
|
-
elsif text?
|
154
|
-
string << ">" << escape(text) << "</#{name}>\n"
|
155
|
-
else
|
156
|
-
string << "/>\n"
|
157
|
-
end
|
158
|
-
string
|
159
|
-
end
|
160
|
-
|
161
|
-
def inspect
|
162
|
-
"<name='#{name}' attrs='#{attrs.inspect}' children.size=#{children.size}>"
|
163
|
-
end
|
164
|
-
|
165
|
-
# the next node
|
166
|
-
def next
|
167
|
-
parent.children[array_index+1]
|
168
|
-
end
|
169
|
-
|
170
|
-
# the first child (equivalent to children.first)
|
171
|
-
def child
|
172
|
-
children.first
|
173
|
-
end
|
174
|
-
|
175
|
-
def add_node(node)
|
176
|
-
node.array_index = children.size
|
177
|
-
children.push( node )
|
178
|
-
end
|
179
|
-
|
180
|
-
########################################################################
|
181
|
-
# FIND and FIND_FIRST (with a little useful xpath)
|
182
|
-
########################################################################
|
183
|
-
|
184
|
-
# Returns an array of nodes. Accepts same xpath strings as find_first.
|
185
|
-
def find(string)
|
186
|
-
(tp, name) = string.split('::')
|
187
|
-
case tp
|
188
|
-
when 'child'
|
189
|
-
find_children(name)
|
190
|
-
when 'descendant'
|
191
|
-
find_descendants(name)
|
192
|
-
when 'following-sibling'
|
193
|
-
find_following_siblings(name)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
# currently must be called with descendant:: or child:: string prefix! e.g.
|
198
|
-
# "descendant::<name>" and "child::<name>" where <name> is the name of the
|
199
|
-
# node you seek)
|
200
|
-
def find_first(string)
|
201
|
-
(tp, name) = string.split('::')
|
202
|
-
case tp
|
203
|
-
when 'child'
|
204
|
-
find_first_child(name)
|
205
|
-
when 'descendant'
|
206
|
-
find_first_descendant(name)
|
207
|
-
when 'following-sibling'
|
208
|
-
find_first_following_sibling(name)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def find_descendants(name, collect_descendants=[])
|
213
|
-
children.each do |child|
|
214
|
-
collect_descendants.push(child) if child.name == name
|
215
|
-
child.find_descendants(name, collect_descendants)
|
216
|
-
end
|
217
|
-
collect_descendants
|
218
|
-
end
|
219
|
-
|
220
|
-
def find_first_descendant(name)
|
221
|
-
self.each do |child_node|
|
222
|
-
if child_node.name == name
|
223
|
-
return child_node
|
2
|
+
require 'axml/autoload'
|
3
|
+
|
4
|
+
module AXML
|
5
|
+
# note that if Autoload must find a suitable parser, it will be set as the
|
6
|
+
# :parser default to be used for future reference.
|
7
|
+
DEFAULTS = {:keep_blanks => false, :parser => nil}
|
8
|
+
PREFERRED = [:xmlparser, :libxml, :libxml_sax, :rexml]
|
9
|
+
CLASS_MAPPINGS = {:xmlparser => 'XMLParser', :libxml => 'LibXML', :libxml_sax => 'libXMLSax', :rexml => 'REXML' }
|
10
|
+
WARN = {:rexml => "Using REXML as parser! This is very slow on large docs!\nCall the method AXML::Autoload.install_instructions for help installing\nsomething FASTER!",
|
11
|
+
}
|
12
|
+
|
13
|
+
# opts:
|
14
|
+
# :parser =
|
15
|
+
def parse(arg, opts={})
|
16
|
+
opts = DEFAULTS.merge opts
|
17
|
+
parser = AXML::Autoload.parser!(opts[:parser])
|
18
|
+
method =
|
19
|
+
if arg.is_a?(String) && File.exist?(arg)
|
20
|
+
:parse_file
|
21
|
+
elsif arg.is_a?(IO)
|
22
|
+
:parse_io
|
23
|
+
elsif arg.is_a?(String)
|
24
|
+
:parse_string
|
224
25
|
else
|
225
|
-
|
26
|
+
raise ArgumentError, "can deal with filenames, Strings, and IO objects.\nDon't know how to work with object of class: #{arg.class}"
|
226
27
|
end
|
227
|
-
|
228
|
-
return nil
|
28
|
+
parser.send(method, arg, opts)
|
229
29
|
end
|
230
30
|
|
231
|
-
def
|
232
|
-
|
31
|
+
def parse_file(file, opts={}) # :nodoc:
|
32
|
+
opts = DEFAULTS.merge opts
|
33
|
+
parser = AXML::Autoload.parser!(opts[:parser])
|
34
|
+
File.open(file) {|fh| parser.parse_io(fh, opts) }
|
233
35
|
end
|
234
36
|
|
235
|
-
|
236
|
-
self.each do |child_node|
|
237
|
-
if child_node.name == name
|
238
|
-
return child_node
|
239
|
-
end
|
240
|
-
end
|
241
|
-
return nil
|
242
|
-
end
|
243
|
-
|
244
|
-
def find_following_siblings(name)
|
245
|
-
parent.children[(array_index+1)..-1].select {|v| v.name == name }
|
246
|
-
end
|
247
|
-
|
248
|
-
def find_first_following_sibling(name)
|
249
|
-
node = nil
|
250
|
-
parent.children[(array_index+1)..-1].each do |sibling|
|
251
|
-
if sibling.name == name
|
252
|
-
node = sibling
|
253
|
-
break
|
254
|
-
end
|
255
|
-
end
|
256
|
-
node
|
257
|
-
end
|
37
|
+
extend AXML
|
258
38
|
|
259
39
|
end
|
260
|
-
|
261
|
-
class AXML::XMLParser < XMLParser
|
262
|
-
|
263
|
-
attr_writer :root
|
264
|
-
|
265
|
-
# returns the first node found in the document
|
266
|
-
def root
|
267
|
-
@root.child
|
268
|
-
end
|
269
|
-
|
270
|
-
def set_no_keep_blanks
|
271
|
-
instance_eval do
|
272
|
-
def endElement(name)
|
273
|
-
unless AXML::NotBlankText_re.match(@cur.text)
|
274
|
-
@cur.text = nil
|
275
|
-
end
|
276
|
-
@cur = @cur.parent
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
# returns text as an array for each occurence of the specified element: [start_index, num_bytes]
|
282
|
-
def set_single_text_indices(el_name)
|
283
|
-
@el_name = el_name
|
284
|
-
instance_eval do
|
285
|
-
def startElement(name, attributes)
|
286
|
-
text =
|
287
|
-
if name == @el_name ; []
|
288
|
-
else ; ''
|
289
|
-
end
|
290
|
-
new_el = ::AXML::El.new(@cur, name, attributes, text, [])
|
291
|
-
@cur.add_node(new_el)
|
292
|
-
@cur = new_el
|
293
|
-
end
|
294
|
-
|
295
|
-
def character(data)
|
296
|
-
if @cur.text.is_a? Array
|
297
|
-
@cur.text << byteIndex
|
298
|
-
else
|
299
|
-
@cur.text << data
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
def endElement(name)
|
304
|
-
if @cur.text.is_a? Array
|
305
|
-
@cur.text << (byteIndex - @cur.text.first)
|
306
|
-
end
|
307
|
-
@cur = @cur.parent
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
# takes opts from AXML::parse method
|
313
|
-
def initialize
|
314
|
-
#@keep_blanks = opts[:keep_blanks]
|
315
|
-
@root = AXML::El.new(nil, "root", {}, '', [])
|
316
|
-
@cur = @root
|
317
|
-
end
|
318
|
-
|
319
|
-
def startElement(name, attributes)
|
320
|
-
new_el = AXML::El.new(@cur, name, attributes, '', [])
|
321
|
-
@cur.add_node(new_el)
|
322
|
-
@cur = new_el
|
323
|
-
end
|
324
|
-
|
325
|
-
def character(data)
|
326
|
-
@cur.text << data
|
327
|
-
end
|
328
|
-
|
329
|
-
def endElement(name)
|
330
|
-
@cur = @cur.parent
|
331
|
-
end
|
332
|
-
|
333
|
-
|
334
|
-
end
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
=begin
|
339
|
-
|
340
|
-
# This parser stores information about where the peaks information is in the
|
341
|
-
# file
|
342
|
-
# The content of the peaks node is an array where the first member is the
|
343
|
-
# start index and the last member is the number of bytes. All other members
|
344
|
-
# should be ignored.
|
345
|
-
class AXML::XMLParser::LazyPeaks < ::AXML::XMLParser
|
346
|
-
|
347
|
-
def startElement(name, attributes)
|
348
|
-
text =
|
349
|
-
if name == 'peaks' ; []
|
350
|
-
else ; ''
|
351
|
-
end
|
352
|
-
new_el = ::AXML::El.new(@cur, name, attributes, text, [])
|
353
|
-
# add the new node to the previous parent node
|
354
|
-
@cur.add_node(new_el)
|
355
|
-
# notice the change in @cur node
|
356
|
-
@cur = new_el
|
357
|
-
end
|
358
|
-
|
359
|
-
def character(data)
|
360
|
-
if @cur.text.is_a? Array
|
361
|
-
@cur.text << byteIndex
|
362
|
-
else
|
363
|
-
@cur.text << data
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
def endElement(name)
|
368
|
-
if @cur.text.is_a? Array
|
369
|
-
@cur.text << (byteIndex - @cur.text.first)
|
370
|
-
end
|
371
|
-
@cur = @cur.parent
|
372
|
-
end
|
373
|
-
|
374
|
-
end
|
375
|
-
|
376
|
-
=end
|