saxerator 0.0.1
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.
- data/.gitignore +8 -0
- data/.rvmrc +38 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE +14 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/benchmark/benchmark.rb +18 -0
- data/benchmark/generate_sample_file.rb +32 -0
- data/lib/saxerator.rb +12 -0
- data/lib/saxerator/configuration.rb +14 -0
- data/lib/saxerator/parser/nokogiri.rb +63 -0
- data/lib/saxerator/string_with_attributes.rb +9 -0
- data/lib/saxerator/version.rb +3 -0
- data/lib/saxerator/xml_node.rb +38 -0
- data/saxerator.gemspec +44 -0
- data/spec/fixtures/flat_blurbs.xml +6 -0
- data/spec/fixtures/nested_elements.xml +53 -0
- data/spec/lib/saxerator_spec.rb +52 -0
- data/spec/spec_helper.rb +6 -0
- metadata +146 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
+
environment_id="1.9.3@saxerator"
|
8
|
+
|
9
|
+
#
|
10
|
+
# First we attempt to load the desired environment directly from the environment
|
11
|
+
# file. This is very fast and efficient compared to running through the entire
|
12
|
+
# CLI and selector. If you want feedback on which environment was used then
|
13
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
14
|
+
#
|
15
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
16
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
17
|
+
then
|
18
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
19
|
+
|
20
|
+
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
21
|
+
then
|
22
|
+
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
23
|
+
fi
|
24
|
+
else
|
25
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
26
|
+
if ! rvm --create "$environment_id"
|
27
|
+
then
|
28
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
29
|
+
return 1
|
30
|
+
fi
|
31
|
+
fi
|
32
|
+
|
33
|
+
if [[ $- == *i* ]] # check for interactive shells
|
34
|
+
then
|
35
|
+
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
36
|
+
else
|
37
|
+
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
38
|
+
fi
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# More info at https://github.com/guard/guard#readme
|
2
|
+
|
3
|
+
guard :bundler do
|
4
|
+
watch('Gemfile')
|
5
|
+
watch(/^saxerator\.gemspec$/)
|
6
|
+
end
|
7
|
+
|
8
|
+
guard :rspec, :cli => '--color --format doc' do
|
9
|
+
watch(%r{^spec/.+_spec\.rb$})
|
10
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^spec/fixtures/.+\.xml$}) { :spec }
|
12
|
+
watch('spec/spec_helper.rb') { :spec }
|
13
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (c) 2012 Bradley Schaefer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
5
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
6
|
+
persons to whom the Software is furnished to do so, subject to the following conditions:
|
7
|
+
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
9
|
+
Software.
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
12
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
13
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
14
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Saxerator
|
2
|
+
=========
|
3
|
+
|
4
|
+
Saxerator is a SAX-based xml parser designed for parsing very large files into manageable chunks. Rather than
|
5
|
+
dealing directly with SAX callback methods, Saxerator gives you Enumerable access to chunks of an xml document.
|
6
|
+
This approach is ideal for large xml files that represent a collection of elements.
|
7
|
+
|
8
|
+
Examples
|
9
|
+
--------
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
Saxerator.parser(File.new("rss.xml")).for_tag(:item).each do |item|
|
13
|
+
puts "#{item['title']}: #{item['author']}"
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
Compatibility
|
18
|
+
-------------
|
19
|
+
This library is known to work with the following rubies:
|
20
|
+
|
21
|
+
* MRI 1.9.3-p125
|
22
|
+
* MRI 1.9.2-p318
|
23
|
+
* JRuby 1.6.7 (with JRUBY_OPTS=--1.9)
|
24
|
+
|
25
|
+
Saxerator may work with other versions with support for Fiber.
|
26
|
+
|
27
|
+
Known incompatible rubies:
|
28
|
+
|
29
|
+
* MRI 1.9.2-p290 (Fiber segfaults)
|
30
|
+
|
31
|
+
FAQ
|
32
|
+
---
|
33
|
+
Why the name 'Saxerator'?
|
34
|
+
|
35
|
+
> It's a combination of SAX + Enumerator.
|
36
|
+
|
37
|
+
Why use Saxerator over regular SAX parsing?
|
38
|
+
|
39
|
+
> Much of the SAX parsing code I've written over the years has fallen into a pattern that Saxerator encapsulates:
|
40
|
+
> marshall a chunk of an XML document into an object, operate on that object, then move on to the
|
41
|
+
> next chunk. Saxerator alleviates the pain of marshalling and allows you to focus solely on operating on the
|
42
|
+
> document chunk.
|
43
|
+
|
44
|
+
Why not DOM parsing?
|
45
|
+
|
46
|
+
> DOM parsers load the entire document into memory. Saxerator only holds a single chunk in memory at a time. If your
|
47
|
+
> document is very large, this can be an important consideration.
|
48
|
+
|
49
|
+
### Acknowledgements ###
|
50
|
+
Saxerator was inspired by [Nori](https://github.com/rubiii/nori) and [Gregory Brown](http://majesticseacreature.com/)'s
|
51
|
+
[Practicing Ruby](http://practicingruby.com/)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.push File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'saxerator'
|
3
|
+
require 'benchmark'
|
4
|
+
|
5
|
+
file = ARGV.shift
|
6
|
+
if !File.exists?(file)
|
7
|
+
puts "Cannot find file #{file}"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
file = File.new(file)
|
11
|
+
|
12
|
+
tag = ARGV.shift || :artist
|
13
|
+
|
14
|
+
count = 0
|
15
|
+
Benchmark.bm do |x|
|
16
|
+
x.report { Saxerator.parser(file).for_tag(tag).each { count = count + 1 } }
|
17
|
+
end
|
18
|
+
puts "#{count} #{tag} elements parsed"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'ipsum'
|
2
|
+
|
3
|
+
filename = ARGV.shift
|
4
|
+
|
5
|
+
unless filename
|
6
|
+
puts "Syntax: ruby #{__FILE__} <filename>"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
num_records = ARGV.shift || 100000
|
11
|
+
num_records = num_records.to_i
|
12
|
+
|
13
|
+
element = <<-eos
|
14
|
+
<artist id="%i">
|
15
|
+
<name>Rock Star %i</name>
|
16
|
+
<active>true</active>
|
17
|
+
<description>%s</description>
|
18
|
+
<genre>Rock,Metal</genre>
|
19
|
+
</artist>
|
20
|
+
eos
|
21
|
+
|
22
|
+
puts "Writing #{num_records} sample records to #{filename}, this will take a while..."
|
23
|
+
|
24
|
+
File.open(filename, 'w') do |f|
|
25
|
+
f.puts '<?xml version="1.0" encoding="UTF-8"?>'
|
26
|
+
f.puts '<artists>'
|
27
|
+
num_records.times do |count|
|
28
|
+
f.puts(element % [count, count, 5.sentences])
|
29
|
+
end
|
30
|
+
f.puts '</artists>'
|
31
|
+
end
|
32
|
+
puts "DONE!"
|
data/lib/saxerator.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'fiber'
|
3
|
+
|
4
|
+
module Saxerator
|
5
|
+
module Parser
|
6
|
+
class Nokogiri
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
def initialize(config, source, tag)
|
10
|
+
@config = config
|
11
|
+
@source = source
|
12
|
+
@tag = tag
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
begin
|
17
|
+
fiber = Fiber.new do
|
18
|
+
document = Document.new(@config, @tag)
|
19
|
+
parser = ::Nokogiri::XML::SAX::Parser.new document
|
20
|
+
parser.parse(@source)
|
21
|
+
end
|
22
|
+
while fiber.alive? do
|
23
|
+
result = fiber.resume
|
24
|
+
yield(result) unless result.nil?
|
25
|
+
end
|
26
|
+
rescue FiberError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Document < ::Nokogiri::XML::SAX::Document
|
31
|
+
attr_accessor :stack
|
32
|
+
|
33
|
+
def initialize(config, tag)
|
34
|
+
@config = config
|
35
|
+
@tag = tag
|
36
|
+
@stack = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_element(name, attrs = [])
|
40
|
+
if stack.size > 0 || name == @tag
|
41
|
+
stack.push Saxerator::XmlNode.new(@config, name, Hash[*attrs.flatten])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def end_element(name)
|
46
|
+
if stack.size > 1
|
47
|
+
last = stack.pop
|
48
|
+
stack.last.add_node last
|
49
|
+
elsif stack.size == 1
|
50
|
+
Fiber.yield(stack.pop.to_hash)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def characters(string)
|
55
|
+
stack.last.add_node(string) unless string.strip.length == 0 || stack.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
alias cdata_block characters
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Saxerator
|
2
|
+
class XmlNode
|
3
|
+
attr_accessor :name, :attributes, :children, :type
|
4
|
+
|
5
|
+
def initialize(config, name, attributes)
|
6
|
+
@config = config
|
7
|
+
self.name = name
|
8
|
+
self.attributes = attributes
|
9
|
+
self.children = []
|
10
|
+
@text = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_node(node)
|
14
|
+
@text = true if node.is_a? String
|
15
|
+
children << node
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
if @text
|
20
|
+
return children.join(' ')
|
21
|
+
else
|
22
|
+
out = {}
|
23
|
+
@children.each do |child|
|
24
|
+
name = child.name
|
25
|
+
if out[name]
|
26
|
+
if !out[name].is_a?(Array)
|
27
|
+
out[name] = [out[name]]
|
28
|
+
end
|
29
|
+
out[name] << child.to_hash
|
30
|
+
else
|
31
|
+
out[name] = child.to_hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
out
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/saxerator.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'saxerator/version'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'saxerator'
|
8
|
+
s.version = Saxerator::VERSION
|
9
|
+
s.authors = ['Bradley Schaefer']
|
10
|
+
s.email = ['bradley.schaefer@gmail.com']
|
11
|
+
s.homepage = 'https://github.com/soulcutter/saxerator'
|
12
|
+
s.summary = 'A SAX-based XML parser for parsing large files into manageable chunks'
|
13
|
+
s.description = 'A SAX-based XML parser for parsing large files into manageable chunks'
|
14
|
+
|
15
|
+
s.required_ruby_version = '>= 1.9.2'
|
16
|
+
|
17
|
+
s.rubyforge_project = 'saxerator'
|
18
|
+
|
19
|
+
s.files = FileList[
|
20
|
+
'LICENSE',
|
21
|
+
'README.md',
|
22
|
+
'saxerator.gemspec',
|
23
|
+
'lib/**/*.rb',
|
24
|
+
'spec/**/*.*',
|
25
|
+
'benchmark/**/*.rb',
|
26
|
+
'Gemfile',
|
27
|
+
'Guardfile',
|
28
|
+
'Rakefile',
|
29
|
+
'.rvmrc',
|
30
|
+
'.gitignore'
|
31
|
+
]
|
32
|
+
s.test_files = FileList['spec/**/*.*']
|
33
|
+
s.executables = []
|
34
|
+
s.require_paths = ['lib']
|
35
|
+
|
36
|
+
s.add_runtime_dependency 'nokogiri'
|
37
|
+
|
38
|
+
s.add_development_dependency 'rspec'
|
39
|
+
s.add_development_dependency 'guard'
|
40
|
+
s.add_development_dependency 'guard-bundler'
|
41
|
+
s.add_development_dependency 'guard-rspec'
|
42
|
+
s.add_development_dependency 'simplecov'
|
43
|
+
s.add_development_dependency 'ipsum'
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<feed xml:lang="en-US" xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<id>/blog</id>
|
4
|
+
<link type="text/html" href="https://example.com/blog" rel="alternate"/>
|
5
|
+
<link type="application/atom+xml" href="https://example.com/blog.atom" rel="self"/>
|
6
|
+
<title>Example Blog</title>
|
7
|
+
<updated>2012-01-01T16:17:00-06:00</updated>
|
8
|
+
<entry>
|
9
|
+
<id>1</id>
|
10
|
+
<published>2012-01-01T16:17:00-06:00</published>
|
11
|
+
<updated>2012-01-01T16:17:00-06:00</updated>
|
12
|
+
<link type="text/html" href="https://example.com/blog/how-to-eat-an-airplane" rel="alternate"/>
|
13
|
+
<title>How to eat an airplane</title>
|
14
|
+
<content type="html"><p>Airplanes are very large, which can present difficulty in digestion.</p>
|
15
|
+
|
16
|
+
<p>The key is to break it down into bite-sized portions and go slowly.</p>
|
17
|
+
</content>
|
18
|
+
<media:thumbnail url="http://www.gravatar.com/avatar/a9eb6ba22e482b71b266daadf9c9a080?s=80"/>
|
19
|
+
<author>
|
20
|
+
<name>Soulcutter</name>
|
21
|
+
</author>
|
22
|
+
<contributor>
|
23
|
+
<name>Jane Doe</name>
|
24
|
+
</contributor>
|
25
|
+
<contributor>
|
26
|
+
<name>Leviticus Alabaster</name>
|
27
|
+
</contributor>
|
28
|
+
</entry>
|
29
|
+
<entry>
|
30
|
+
<id>2</id>
|
31
|
+
<published>2012-01-02T18:19:00-06:00</published>
|
32
|
+
<updated>2012-01-02T18:19:00-06:00</updated>
|
33
|
+
<link type="text/html" href="https://example.com/blog/sample-data-is-hard-work" rel="alternate"/>
|
34
|
+
<title>Sample data is hard work</title>
|
35
|
+
<content type="html"><p>People don't believe me when I tell them how tedious it is.</p></content>
|
36
|
+
<media:thumbnail url="http://www.gravatar.com/avatar/742798d92b705cfeba3937e122974982?s=80"/>
|
37
|
+
<author>
|
38
|
+
<name>Bradley Schaefer</name>
|
39
|
+
</author>
|
40
|
+
</entry>
|
41
|
+
<entry>
|
42
|
+
<id>3</id>
|
43
|
+
<published>2012-01-15T21:22:00-06:00</published>
|
44
|
+
<updated>2012-01-15T21:22:00-06:00</updated>
|
45
|
+
<link type="text/html" href="https://example.com/blog/three-should-be-enough" rel="alternate"/>
|
46
|
+
<title>Three should be enough</title>
|
47
|
+
<content type="html"><p>EOM</p></content>
|
48
|
+
<media:thumbnail url="http://www.gravatar.com/avatar/a9eb6ba22e482b71b266daadf9c9a080?s=80"/>
|
49
|
+
<author>
|
50
|
+
<name>Soulcutter</name>
|
51
|
+
</author>
|
52
|
+
</entry>
|
53
|
+
</feed>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Saxerator do
|
4
|
+
def fixture_file(name)
|
5
|
+
File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', name))
|
6
|
+
end
|
7
|
+
|
8
|
+
context ".parser" do
|
9
|
+
subject { parser }
|
10
|
+
let(:parser) { Saxerator.parser(xml) }
|
11
|
+
|
12
|
+
context "with a string with blurbs" do
|
13
|
+
let(:xml) { "<blurbs><blurb>one</blurb><blurb>two</blurb><blurb>three</blurb></blurbs>" }
|
14
|
+
|
15
|
+
it "should parse simple strings" do
|
16
|
+
results = []
|
17
|
+
subject.for_tag(:blurb).each { |x| results << x }
|
18
|
+
results.should == ['one', 'two', 'three']
|
19
|
+
end
|
20
|
+
|
21
|
+
context "and one non-blurb" do
|
22
|
+
let(:xml) { "<blurbs><blurb>one</blurb><blurb>two</blurb><blurb>three</blurb><notablurb>four</notablurb></blurbs>" }
|
23
|
+
it "should only parse the requested tag" do
|
24
|
+
results = []
|
25
|
+
subject.for_tag(:blurb).each { |x| results << x }
|
26
|
+
results.should == ['one', 'two', 'three']
|
27
|
+
subject.for_tag(:notablurb).each { |x| results << x }
|
28
|
+
results.should == ['one', 'two', 'three', 'four']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with a file with blurbs" do
|
34
|
+
let(:xml) { fixture_file('flat_blurbs.xml') }
|
35
|
+
|
36
|
+
it "should parse simple strings" do
|
37
|
+
results = []
|
38
|
+
subject.for_tag(:blurb).each { |x| results << x }
|
39
|
+
results.should == ['one', 'two', 'three']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with a file with nested elements" do
|
44
|
+
let(:xml) { fixture_file('nested_elements.xml') }
|
45
|
+
subject { parser.for_tag(:entry).first }
|
46
|
+
|
47
|
+
specify { subject['title'].should == 'How to eat an airplane' }
|
48
|
+
specify { subject['author'].should == {'name' => 'Soulcutter'} }
|
49
|
+
specify { subject['contributor'].should == [{'name' => 'Jane Doe'}, {'name' => 'Leviticus Alabaster'}] }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saxerator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bradley Schaefer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nokogiri
|
16
|
+
requirement: &70348029624860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70348029624860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70348029624300 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70348029624300
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard
|
38
|
+
requirement: &70348029623840 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70348029623840
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-bundler
|
49
|
+
requirement: &70348029623320 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70348029623320
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: guard-rspec
|
60
|
+
requirement: &70348029622860 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70348029622860
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: &70348029622300 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70348029622300
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: ipsum
|
82
|
+
requirement: &70348029621880 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70348029621880
|
91
|
+
description: A SAX-based XML parser for parsing large files into manageable chunks
|
92
|
+
email:
|
93
|
+
- bradley.schaefer@gmail.com
|
94
|
+
executables: []
|
95
|
+
extensions: []
|
96
|
+
extra_rdoc_files: []
|
97
|
+
files:
|
98
|
+
- LICENSE
|
99
|
+
- README.md
|
100
|
+
- saxerator.gemspec
|
101
|
+
- lib/saxerator/configuration.rb
|
102
|
+
- lib/saxerator/parser/nokogiri.rb
|
103
|
+
- lib/saxerator/string_with_attributes.rb
|
104
|
+
- lib/saxerator/version.rb
|
105
|
+
- lib/saxerator/xml_node.rb
|
106
|
+
- lib/saxerator.rb
|
107
|
+
- spec/fixtures/flat_blurbs.xml
|
108
|
+
- spec/fixtures/nested_elements.xml
|
109
|
+
- spec/lib/saxerator_spec.rb
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
- benchmark/benchmark.rb
|
112
|
+
- benchmark/generate_sample_file.rb
|
113
|
+
- Gemfile
|
114
|
+
- Guardfile
|
115
|
+
- Rakefile
|
116
|
+
- .rvmrc
|
117
|
+
- .gitignore
|
118
|
+
homepage: https://github.com/soulcutter/saxerator
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.9.2
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project: saxerator
|
138
|
+
rubygems_version: 1.8.11
|
139
|
+
signing_key:
|
140
|
+
specification_version: 3
|
141
|
+
summary: A SAX-based XML parser for parsing large files into manageable chunks
|
142
|
+
test_files:
|
143
|
+
- spec/fixtures/flat_blurbs.xml
|
144
|
+
- spec/fixtures/nested_elements.xml
|
145
|
+
- spec/lib/saxerator_spec.rb
|
146
|
+
- spec/spec_helper.rb
|