axml 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/LICENSE +13 -0
  2. data/README +79 -0
  3. data/Rakefile +203 -0
  4. data/lib/axml.rb +227 -0
  5. data/specs/axml_spec.rb +222 -0
  6. data/specs/spec_helper.rb +57 -0
  7. metadata +55 -0
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2006, The University of Texas at Austin("U.T. Austin"). All rights reserved.
2
+
3
+ Software by John T. Prince under the direction of Edward M. Marcotte.
4
+
5
+ By using this software the USER indicates that he or she has read, understood and will comply with the following:
6
+
7
+ U. T. Austin hereby grants USER permission to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of this software and its documentation for any purpose and without fee, provided that a full copy of this notice is included with the software and its documentation.
8
+
9
+ Title to copyright this software and its associated documentation shall at all times remain with U. T. Austin. No right is granted to use in advertising, publicity or otherwise any trademark, service mark, or the name of U. T. Austin.
10
+
11
+ This software and any associated documentation are provided "as is," and U. T. AUSTIN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. U. T. Austin, The University of Texas System, its Regents, officers, and employees shall not be liable under any circumstances for any direct, indirect, special, incidental, or consequential damages with respect to any claim by USER or any third party on account of or arising from the use, or inability to use, this software or its associated documentation, even if U. T. Austin has been advised of the possibility of those damages.
12
+
13
+ Submit software operation questions to: John T. Prince, Institute for Cellular and Molecular Biology, U. T. Austin, Austin, Texas 78712.
data/README ADDED
@@ -0,0 +1,79 @@
1
+ AXML
2
+ ====
3
+
4
+ AXML - Provides a simple DOM for working with XML (using XMLParser under the
5
+ hood) that can serve as a drop in replacement for much of the basic libxml
6
+ functionality (e.g., each, children, child, find_first, find, next). AXML
7
+ comes from the idea that XML should be AXED (or at least simple to use!)
8
+ to use).
9
+
10
+ Description
11
+ -----------
12
+
13
+ Parses elements, attributes, and text(content), and nothing more. Should be
14
+ very easy to extend and modify for special cases. It is roughly as fast as
15
+ libxml, although it currently reads in the entire document first (however,
16
+ this is memory efficient - nodes are implemented using Struct).
17
+
18
+ Examples
19
+ --------
20
+ string_or_io = "
21
+ <n1>
22
+ <n2 size='big'>
23
+ <n3>words here</n3>
24
+ <n3></n3>
25
+ </n2>
26
+ <n2 size='small'>
27
+ <n3 id='3'></n3)
28
+ </n2>
29
+ </n1>
30
+ "
31
+
32
+ ## Read a string or io
33
+ n1_node = AXML.parse(string_or_io)
34
+
35
+ ## Read a file
36
+ n1_node = AXML.parse_file(filename)
37
+
38
+ ## Access children
39
+ n1_node.children # -> [array]
40
+ n1_node.each {|child| # do something with child }
41
+
42
+ ## Get attributes and text
43
+ n2_node['size'] == 'big'
44
+ n3_node = n2_node.child
45
+ n3_node.text # -> 'words here'
46
+ n3_node.content # -> [same]
47
+
48
+ ## Traverse nodes with next and child
49
+ n2_node = n1_node.child
50
+ the_other_n2_node = n2_node.next
51
+ the_other_n2_node.next = nil
52
+
53
+ ## Does a little xpath
54
+ n3_node = n1_node.find_first('descendant::n3')
55
+ n1_node.find_first('child::n3') # -> nil
56
+ n1_node.find('descendant::n3') # -> [array of all 3 <n3> nodes]
57
+ n1_node.find('child::n2') # -> [array of 2 <n2> nodes]
58
+
59
+ All Examples (see specs/axml_spec.rb)
60
+
61
+ - reads xml strings with "AXML.parse"
62
+ - reads file handles with "AXML.parse"
63
+ - reads files with "AXML.parse_file"
64
+ - can access subnodes with "children" or "kids"
65
+ - accesses attributes with "[]"
66
+ - can "find_first_descendant"
67
+ - can "find_first_child"
68
+ - can "find" with a little xpath
69
+ - can do some find_first xpath
70
+ - can drop nodes with "drop"
71
+ - can return "child" node
72
+ - can return "next" node
73
+ - "to_s" gives xml
74
+
75
+ Installation
76
+ ------------
77
+
78
+ gem install axml
79
+
data/Rakefile ADDED
@@ -0,0 +1,203 @@
1
+ require 'rake'
2
+ require 'rubygems'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/clean'
6
+ require 'fileutils'
7
+ require 'spec/rake/spectask'
8
+
9
+ ###############################################
10
+ # GLOBAL
11
+ ###############################################
12
+
13
+ FL = FileList
14
+ NAME = "axml"
15
+
16
+ readme = "README"
17
+
18
+ rdoc_extra_includes = [readme, "LICENSE"]
19
+ rdoc_options = ['--main', readme, '--title', NAME]
20
+
21
+ lib_files = FL["lib/**/*"]
22
+ dist_files = lib_files + FL[readme, "LICENSE", "Rakefile", "{specs}/**/*"]
23
+ changelog = 'CHANGELOG'
24
+
25
+ ###############################################
26
+ # ENVIRONMENT
27
+ ###############################################
28
+ ENV["OS"] == "Windows_NT" ? WIN32 = true : WIN32 = false
29
+ $gemcmd = "gem"
30
+ if WIN32
31
+ unless ENV["TERM"] == "cygwin"
32
+ $gemcmd << ".cmd"
33
+ end
34
+ end
35
+
36
+ ###############################################
37
+ # DOC
38
+ ###############################################
39
+ Rake::RDocTask.new do |rd|
40
+ rd.main = readme
41
+ rd.rdoc_files.include rdoc_extra_includes
42
+ rd.options.push( *rdoc_options )
43
+ end
44
+
45
+ ###############################################
46
+ # TESTS
47
+ ###############################################
48
+
49
+
50
+ task :ensure_gem_is_uninstalled do
51
+ reply = `#{$gemcmd} list -l #{NAME}`
52
+ if reply.include? NAME + " ("
53
+ puts "GOING to uninstall gem '#{NAME}' for testing"
54
+ if WIN32
55
+ %x( #{$gemcmd} uninstall -x #{NAME} )
56
+ else
57
+ %x( sudo #{$gemcmd} uninstall -x #{NAME} )
58
+ end
59
+ end
60
+ end
61
+
62
+ namespace :spec do
63
+ task :autotest do
64
+ require './specs/rspec_autotest'
65
+ RspecAutotest.run
66
+ end
67
+ end
68
+
69
+ desc "Run specs"
70
+ Spec::Rake::SpecTask.new('spec') do |t|
71
+ Rake::Task[:ensure_gem_is_uninstalled].invoke
72
+ t.libs = ['lib']
73
+ t.spec_files = FileList['specs/**/*_spec.rb']
74
+ end
75
+
76
+ desc "Run specs and output specdoc"
77
+ Spec::Rake::SpecTask.new('specl') do |t|
78
+ Rake::Task[:ensure_gem_is_uninstalled].invoke
79
+ t.spec_files = FileList['specs/**/*_spec.rb']
80
+ t.libs = ['lib']
81
+ t.spec_opts = ['--format', 'specdoc' ]
82
+ end
83
+
84
+ desc "Run all specs with RCov"
85
+ Spec::Rake::SpecTask.new('rcov') do |t|
86
+ Rake::Task[:ensure_gem_is_uninstalled].invoke
87
+ t.spec_files = FileList['specs/**/*_spec.rb']
88
+ t.rcov = true
89
+ t.libs = ['lib']
90
+ t.rcov_opts = ['--exclude', 'specs']
91
+ end
92
+
93
+ #task :spec do
94
+ # uninstall_gem
95
+ # # files that match a key word
96
+ # files_to_run = ENV['SPEC'] || FileList['specs/**/*_spec.rb']
97
+ # if ENV['SPECM']
98
+ # files_to_run = files_to_run.select do |file|
99
+ # file.include?(ENV['SPECM'])
100
+ # end
101
+ # end
102
+ # files_to_run.each do |spc|
103
+ # system "ruby -I lib -S spec #{spc} --format specdoc"
104
+ # end
105
+ #end
106
+
107
+ ###############################################
108
+ # PACKAGE / INSTALL / UNINSTALL
109
+ ###############################################
110
+
111
+ def get_summary(readme)
112
+ string = ''
113
+ collect = false
114
+ IO.foreach(readme) do |line|
115
+ if collect
116
+ if line =~ /[^\s]/
117
+ string << line
118
+ else
119
+ break
120
+ end
121
+ elsif line =~ /^AXML - .*/
122
+ string << line
123
+ collect = true
124
+ end
125
+ end
126
+ string.gsub!("\n", " ")
127
+ end
128
+
129
+ # looks for a header, collects the paragraph after the space
130
+ def get_section(header, file)
131
+ get_space = false
132
+ found_space = false
133
+ string = ''
134
+ IO.foreach(file) do |line|
135
+ if found_space
136
+ if line =~ /[^\s]/
137
+ string << line
138
+ else
139
+ break
140
+ end
141
+ elsif get_space
142
+ if line !~ /[^\s]/
143
+ found_space = true
144
+ get_space = false
145
+ end
146
+ elsif line =~ /^#{header}/
147
+ get_space = true
148
+ end
149
+ end
150
+ string.gsub!("\n", ' ')
151
+ end
152
+
153
+ def get_description(readme)
154
+ get_section('Description', readme)
155
+ end
156
+
157
+ tm = Time.now
158
+ gemspec = Gem::Specification.new do |t|
159
+ description = get_description(readme)
160
+ summary = get_summary(readme)
161
+ t.platform = Gem::Platform::RUBY
162
+ t.name = NAME
163
+ t.version = IO.readlines(changelog).grep(/##.*version/).pop.split(/\s+/).last.chomp
164
+ t.summary = summary
165
+ t.date = "#{tm.year}-#{tm.month}-#{tm.day}"
166
+ t.email = "jprince@icmb.utexas.edu"
167
+ t.description = description
168
+ t.has_rdoc = true
169
+ t.authors = ["John Prince"]
170
+ t.files = dist_files
171
+ t.rdoc_options = rdoc_options
172
+ t.extra_rdoc_files = rdoc_extra_includes
173
+ t.executables = FL["bin/*"].map {|file| File.basename(file) }
174
+ t.requirements << 'xmlparser is needed right now'
175
+ t.test_files = FL["specs/*_spec.rb"]
176
+ end
177
+
178
+ desc "Create packages."
179
+ Rake::GemPackageTask.new(gemspec) do |pkg|
180
+ #pkg.need_zip = true
181
+ pkg.need_tar = true
182
+ end
183
+
184
+ task :remove_pkg do
185
+ FileUtils.rm_rf "pkg"
186
+ end
187
+
188
+
189
+ task :install => [:reinstall]
190
+
191
+ desc "uninstalls the package, packages a fresh one, and installs"
192
+ task :reinstall => [:remove_pkg, :clean, :package] do
193
+ reply = `#{$gemcmd} list -l #{NAME}`
194
+ if reply.include?(NAME + " (")
195
+ %x( #{$gemcmd} uninstall -a -x #{NAME} )
196
+ end
197
+ FileUtils.cd("pkg") do
198
+ cmd = "#{$gemcmd} install #{NAME}*.gem"
199
+ puts "EXECUTING: #{cmd}"
200
+ system cmd
201
+ end
202
+ end
203
+
data/lib/axml.rb ADDED
@@ -0,0 +1,227 @@
1
+ require 'xmlparser'
2
+
3
+ class AXML
4
+
5
+ def self.parse_file(file)
6
+ root = nil
7
+ File.open(file) do |fh|
8
+ root = parse(fh)
9
+ end
10
+ root
11
+ end
12
+
13
+ # Returns the root node (as Element) or nodes (as Array)
14
+ def self.parse(stream)
15
+ parser = AXML::XMLParser.new
16
+ parser.parse(stream)
17
+ parser.root
18
+ end
19
+
20
+ end
21
+
22
+ AXML::El = Struct.new(:parent, :name, :attrs, :text, :children, :array_index)
23
+
24
+ class AXML::El
25
+ @@tabs = ["", " ", " ", " ", " ", " ", " "]
26
+ include Enumerable
27
+
28
+ @@depth = 0
29
+ #attr_accessor :name, :attrs, :text, :children, :parent
30
+ # keeps track of location in array
31
+ #attr_accessor :array_index
32
+
33
+ alias_method :content, :text
34
+ alias_method :content=, :text=
35
+ alias_method :kids, :children
36
+ alias_method :kids=, :children=
37
+
38
+ def [](attribute_string)
39
+ attrs[attribute_string]
40
+ end
41
+
42
+ # accepts same xpath strings as find_first
43
+ # returns an array of nodes
44
+ def find(string)
45
+ (tp, name) = string.split('::')
46
+ case tp
47
+ when 'child'
48
+ find_children(name)
49
+ when 'descendant'
50
+ find_descendants(name)
51
+ when 'following-sibling'
52
+ find_following_siblings(name)
53
+ end
54
+ end
55
+
56
+ def find_descendants(name, collect_descendants=[])
57
+ children.each do |child|
58
+ collect_descendants.push(child) if child.name == name
59
+ child.find_descendants(name, collect_descendants)
60
+ end
61
+ collect_descendants
62
+ end
63
+
64
+ def find_children(name)
65
+ children.select {|v| v.name == name }
66
+ end
67
+
68
+
69
+ # currently must be called with descendent:: or child:: string prefix! e.g.
70
+ # "descendant::<name>" and "child::<name>" where <name> is the name of the
71
+ # node you seek)
72
+ def find_first(string)
73
+ (tp, name) = string.split('::')
74
+ case tp
75
+ when 'child'
76
+ find_first_child(name)
77
+ when 'descendant'
78
+ find_first_descendant(name)
79
+ when 'following-sibling'
80
+ find_first_following_sibling(name)
81
+ end
82
+ end
83
+
84
+ def find_first_descendant(name)
85
+ self.each do |child_node|
86
+ if child_node.name == name
87
+ return child_node
88
+ else
89
+ return child_node.find_first_descendant(name)
90
+ end
91
+ end
92
+ return nil
93
+ end
94
+
95
+ def find_first_child(name)
96
+ self.each do |child_node|
97
+ if child_node.name == name
98
+ return child_node
99
+ end
100
+ end
101
+ return nil
102
+ end
103
+
104
+ def find_following_siblings(name)
105
+ parent.children[(array_index+1)..-1].select {|v| v.name == name }
106
+ end
107
+
108
+ def find_first_following_sibling(name)
109
+ node = nil
110
+ parent.children[(array_index+1)..-1].each do |sibling|
111
+ if sibling.name == name
112
+ node = sibling
113
+ break
114
+ end
115
+ end
116
+ node
117
+ end
118
+
119
+ def children?
120
+ children.size > 0
121
+ end
122
+ alias_method :child?, :children?
123
+
124
+
125
+ def each(&block)
126
+ children.each do |child|
127
+ block.call(child)
128
+ end
129
+ end
130
+
131
+ # drops the current element from the list of its parents children
132
+ def drop
133
+ parent.children.delete(self)
134
+ end
135
+
136
+ def drop_child(node)
137
+ found_it = false
138
+ found_index = nil
139
+ children.each_with_index do |v,i|
140
+ if found_it
141
+ v.array_index = i - 1
142
+ end
143
+ if v.object_id == node.object_id
144
+ found_index = i
145
+ found_it = true
146
+ end
147
+ end
148
+ children.delete_at(found_index) if found_index
149
+ end
150
+
151
+ def tabs
152
+ @@tabs[@@depth]
153
+ end
154
+
155
+ def to_s
156
+ attstring = ""
157
+ if attrs.size > 0
158
+ attstring = " " + attrs.collect { |k,v| "#{k}=\"#{v}\"" }.join(" ")
159
+ end
160
+ string = "#{tabs}<#{name}#{attstring}"
161
+ if children.size > 0
162
+ string << ">\n"
163
+ @@depth += 1
164
+ string << children.collect {|child| child.to_s }.join("")
165
+ @@depth -= 1
166
+ string << "#{tabs}</#{name}>\n"
167
+ else
168
+ string << "/>\n"
169
+ end
170
+ string
171
+ end
172
+
173
+ def inspect
174
+ "<name='#{name}' attrs='#{attrs.inspect}' children.size=#{children.size}>"
175
+ end
176
+
177
+ # the next node
178
+ def next
179
+ parent.children[array_index+1]
180
+ end
181
+
182
+ # the first child (equivalent to children.first)
183
+ def child
184
+ children.first
185
+ end
186
+
187
+ def add_node(node)
188
+ node.array_index = children.size
189
+ children.push( node )
190
+ end
191
+
192
+ end
193
+
194
+ class AXML::XMLParser < XMLParser
195
+
196
+ attr_writer :root
197
+
198
+ # returns the first node found in the document
199
+ def root
200
+ @root.child
201
+ end
202
+
203
+ def initialize
204
+ @root = AXML::El.new(nil, "root", {}, '', [])
205
+ @cur = @root
206
+ end
207
+
208
+ def startElement(name, attributes)
209
+ new_el = AXML::El.new(@cur, name, attributes, '', [])
210
+ # add the new node to the previous parent node
211
+ @cur.add_node(new_el)
212
+ # notice the change in @cur node
213
+ @cur = new_el
214
+ #@cur.text = "" ## in initialization now..
215
+ end
216
+
217
+ def endElement(name)
218
+ @cur = @cur.parent
219
+ end
220
+
221
+ def character(data)
222
+ @cur.text << data
223
+ end
224
+
225
+ end
226
+
227
+
@@ -0,0 +1,222 @@
1
+ require File.expand_path( File.dirname(__FILE__) + '/spec_helper' )
2
+
3
+ require 'axml'
4
+
5
+ describe AXML do
6
+
7
+ before(:each) do
8
+ @xml_string = <<END
9
+ <xml>
10
+ <doc1>
11
+ <dog name="spot" height="23" weight="13">
12
+ <flea name="ouchy" height="20" weight="10"/>
13
+ <flea name="crawly" height="22" weight="9"/>
14
+ </dog>
15
+ </doc1>
16
+ <doc2>
17
+ <dog name="billy" height="5" weight="3">
18
+ </dog>
19
+ </doc2>
20
+ </xml>
21
+ END
22
+ @small_xml_string = <<END
23
+ <first>
24
+ <inner1 name="hello">
25
+ </inner1>
26
+ <inner2>
27
+ </inner2>
28
+ </first>
29
+ END
30
+ @xml_large_string = <<END
31
+ <n1>
32
+ <n2 id='1'>
33
+ <n3 id='1'> </n3>
34
+ <n3 id='2'> </n3>
35
+ <n3b id='5'></n3b>
36
+ <n3b id='6'></n3b>
37
+ </n2>
38
+ <n2 id='2'>
39
+ <n3 id='3'> </n3>
40
+ <n3 id='4'> </n3>
41
+ </n2>
42
+ </n1>
43
+ END
44
+ end
45
+
46
+ it 'reads xml strings with "AXML.parse"' do
47
+ node = AXML.parse(@small_xml_string)
48
+
49
+ node.class.should == AXML::El
50
+ node.name.should == 'first'
51
+ node.children.first.name.should == 'inner1'
52
+ node.kids.first.name.should == 'inner1'
53
+ end
54
+
55
+ it 'reads file handles with "AXML.parse"' do
56
+ file = File.dirname(__FILE__) + '/axml.tmp'
57
+ File.open(file, 'w') {|fh| fh.puts @xml_string}
58
+ fh = File.open(file)
59
+ root = AXML.parse(fh)
60
+ fh.close
61
+ root.name.should == 'xml'
62
+ root.kids[0].kids.first.attrs["name"].should == 'spot'
63
+ File.unlink(file) if File.exist? file
64
+ end
65
+
66
+ it 'reads files with "AXML.parse_file"' do
67
+ file = File.dirname(__FILE__) + '/axml.tmp'
68
+ File.open(file, 'w') {|fh| fh.puts @xml_string}
69
+ root = AXML.parse_file(file)
70
+ root.name.should == 'xml'
71
+ root.kids[0].kids.first.attrs["name"].should == 'spot'
72
+ File.unlink(file) if File.exist? file
73
+ end
74
+
75
+ it 'can access subnodes with "children" or "kids"' do
76
+ node = AXML.parse(@small_xml_string)
77
+ node.name.should == 'first'
78
+ node.kids.zip(%w(inner1 inner2)) do |kd,nm|
79
+ kd.name.should == nm
80
+ end
81
+ end
82
+
83
+ it 'accesses attributes with "[]"' do
84
+ root = AXML.parse(@xml_string)
85
+ dog_node = root.kids[0].kids[0]
86
+ dog_node.name.should == 'dog'
87
+ dog_node['name'].should == 'spot'
88
+ dog_node['height'].should == '23'
89
+ end
90
+
91
+ it 'can "find_first_descendant"' do
92
+ root = AXML.parse(@xml_string)
93
+ doc1_node = root.find_first_descendant('doc1')
94
+ doc1_node.name.should == 'doc1'
95
+ doc1_node.children.size.should == 1
96
+ doc1_node.find_first_descendant('xml').should == nil
97
+ doc1_node.find_first_descendant('doc1').should == nil
98
+ child_node = root.find_first_descendant('flea')
99
+ child_node.name.should == 'flea'
100
+ child_node['name'].should == 'ouchy'
101
+ child_node.find_first_descendant('flea').should == nil
102
+ end
103
+
104
+ it 'can "find_first_child"' do
105
+ root = AXML.parse(@xml_string)
106
+ doc1_node = root.find_first_child('doc1')
107
+ doc1_node.name.should == 'doc1'
108
+ doc1_node.children.size.should == 1
109
+ doc1_node.find_first_child('xml').should == nil
110
+ doc1_node.find_first_child('doc1').should == nil
111
+ dog_node = doc1_node.find_first_child('dog')
112
+ dog_node.name.should == 'dog'
113
+ dog_node['name'].should == 'spot'
114
+ doc2_node = root.find_first_child('doc2')
115
+ doc2_node.name.should == 'doc2'
116
+ doc2_node.children.size.should == 1
117
+ end
118
+
119
+ it 'can "find" with a little xpath' do
120
+ root = AXML.parse(@xml_large_string)
121
+ nodes = root.find('child::n2')
122
+ nodes.size.should == 2
123
+ nodes.each {|v| v.name.should == 'n2' }
124
+ nodes.each_with_index {|v,i| v['id'].should == (i+1).to_s }
125
+
126
+ nodes = root.find('descendant::n3')
127
+ nodes.size.should == 4
128
+ nodes.each {|v| v.name.should == 'n3' }
129
+ nodes.each_with_index {|v,i| v['id'].should == (i+1).to_s }
130
+ end
131
+
132
+ it 'can do some find_first xpath' do
133
+ root = AXML.parse(@xml_string)
134
+ flea_node = root.find_first('descendant::flea')
135
+ flea_node.name.should == 'flea'
136
+ flea_node['name'].should == 'ouchy'
137
+ root.find_first('child::flea').should be_nil
138
+ root.find_first('child::doc2').name.should == 'doc2'
139
+ end
140
+
141
+ it 'can drop nodes with "drop"' do
142
+ root = AXML.parse(@xml_string)
143
+ root.children[0].children[0].drop
144
+ to_string = <<END
145
+ <xml>
146
+ <doc1/>
147
+ <doc2>
148
+ <dog name="billy" weight="3" height="5"/>
149
+ </doc2>
150
+ </xml>
151
+ END
152
+ root.to_s.should == to_string
153
+ end
154
+
155
+ it 'can return "child" node' do
156
+ root = AXML.parse(@xml_string)
157
+ doc1 = root.child
158
+ doc1.name.should == 'doc1'
159
+ dog = doc1.child
160
+ dog.name.should == 'dog'
161
+ dog['name'].should == 'spot'
162
+ flea = dog.child
163
+ flea.name.should == 'flea'
164
+ flea['name'].should == 'ouchy'
165
+ flea.child.should == nil
166
+ end
167
+
168
+ it 'can return "next" node' do
169
+ root = AXML.parse(@xml_string)
170
+ root.next.should == nil
171
+ doc1 = root.child
172
+ doc2 = doc1.next
173
+ doc2.name.should == 'doc2'
174
+ doc2.next.should == nil
175
+ dog = doc1.child
176
+ dog.name.should == 'dog'
177
+ dog.next.should == nil
178
+ flea2 = dog.child.next
179
+ flea2.name.should == 'flea'
180
+ flea2['name'].should == 'crawly'
181
+ flea2.next.should == nil
182
+ end
183
+
184
+ it 'can find "following-sibling"' do
185
+ n1 = AXML.parse(@xml_large_string)
186
+ n3 = n1.child.child
187
+ n3.name.should == 'n3'
188
+ n3id2 = n3.find_first("following-sibling::n3")
189
+ n3id2['id'].should == '2'
190
+ n3b = n3.find_first("following-sibling::n3b")
191
+ n3b['id'].should == '5'
192
+ n3b.find_first("following-sibling::n3").should == nil
193
+ end
194
+
195
+ it '"to_s" gives xml' do
196
+ root = AXML.parse(@xml_string)
197
+ to_string = <<END
198
+ <xml>
199
+ <doc1>
200
+ <dog name="spot" weight="13" height="23">
201
+ <flea name="ouchy" weight="10" height="20"/>
202
+ <flea name="crawly" weight="9" height="22"/>
203
+ </dog>
204
+ </doc1>
205
+ <doc2>
206
+ <dog name="billy" weight="3" height="5"/>
207
+ </doc2>
208
+ </xml>
209
+ END
210
+ root.to_s.should == to_string
211
+ end
212
+
213
+ it 'can get many attributes at once with values_at (not supported by libxml)' do
214
+ root = AXML.parse(@xml_string)
215
+ dog = root.child.child.child
216
+ exp = %w(ouchy 20 10)
217
+ reply = dog.attrs.values_at('name', 'height', 'weight')
218
+ reply.should == exp
219
+ end
220
+
221
+
222
+ end
@@ -0,0 +1,57 @@
1
+
2
+ gem 'rspec'
3
+
4
+
5
+ def xdescribe(*args)
6
+ puts "#{args.join(' ')}"
7
+ puts "**SKIPPING**"
8
+ end
9
+
10
+ def Xdescribe(*args)
11
+ xdescribe(*args)
12
+ end
13
+
14
+ def xit(*args)
15
+ puts "- SKIPPING: #{args.join(' ')}"
16
+ end
17
+
18
+ def silent(&block)
19
+ tmp = $VERBOSE ; $VERBOSE = nil
20
+ block.call
21
+ $VERBOSE = tmp
22
+ end
23
+
24
+ silent {
25
+ ROOT_DIR = File.dirname(__FILE__) + '/..'
26
+ SPEC_DIR = File.dirname(__FILE__)
27
+ }
28
+
29
+
30
+ class String
31
+ #alias_method :exist?, exist_as_a_file?
32
+ #alias_method exist_as_a_file?, exist?
33
+ def exist?
34
+ File.exist? self
35
+ end
36
+ def exist_as_a_file?
37
+ File.exist? self
38
+ end
39
+ end
40
+
41
+ describe "a cmdline program", :shared => true do
42
+ before(:all) do
43
+ testdir = File.dirname(__FILE__)
44
+ libdir = testdir + '/../lib'
45
+ bindir = testdir + '/../bin'
46
+ progname = "fasta_shaker.rb"
47
+ @cmd = "ruby -I #{libdir} #{bindir}/#{@progname} "
48
+ end
49
+
50
+ it 'gives usage when called with no args' do
51
+ reply = `#{@cmd}`
52
+ reply.should =~ /usage/i
53
+ end
54
+
55
+ end
56
+
57
+
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: axml
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.2
7
+ date: 2007-10-19 00:00:00 -05:00
8
+ summary: AXML - Provides a simple DOM for working with XML (using XMLParser under the hood) that can serve as a drop in replacement for much of the basic libxml functionality (e.g., each, children, child, find_first, find, next). AXML comes from the idea that XML should be AXED (or at least simple to use!) to use).
9
+ require_paths:
10
+ - lib
11
+ email: jprince@icmb.utexas.edu
12
+ homepage:
13
+ rubyforge_project:
14
+ description: Parses elements, attributes, and text(content), and nothing more. Should be very easy to extend and modify for special cases. It is roughly as fast as libxml, although it currently reads in the entire document first (however, this is memory efficient - nodes are implemented using Struct).
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - John Prince
31
+ files:
32
+ - lib/axml.rb
33
+ - README
34
+ - LICENSE
35
+ - Rakefile
36
+ - specs/spec_helper.rb
37
+ - specs/axml_spec.rb
38
+ test_files:
39
+ - specs/axml_spec.rb
40
+ rdoc_options:
41
+ - --main
42
+ - README
43
+ - --title
44
+ - axml
45
+ extra_rdoc_files:
46
+ - README
47
+ - LICENSE
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ requirements:
53
+ - xmlparser is needed right now
54
+ dependencies: []
55
+