easy_sax 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +145 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/easy_sax.gemspec +29 -0
- data/lib/easy_sax.rb +22 -0
- data/lib/easy_sax/parse_error.rb +2 -0
- data/lib/easy_sax/parser.rb +89 -0
- data/lib/easy_sax/simple_element.rb +34 -0
- data/lib/easy_sax/version.rb +3 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 728c5b578b32cb27cbb786cd5ee990b7ca03c2b8
|
4
|
+
data.tar.gz: 02ce51a239add7f7b57c1950e61bb851303baf35
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b01b16e0e38a178410e74f2550bc0229ff2ea14638adceedbab648a6b98861219e41c7dcc502d4a8cca1df22159d746f0a02ddbfc22aaacf5a5010999afd573
|
7
|
+
data.tar.gz: 6d00ec699b5387f6665b3e2350a69c01c365d00d558e88d1c3a1284b5ff6f0c7dc182a4365848ada8032a19eacc4fe1ea16c8033391717d10b5206e0e1d6ece0
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Eric Northam
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# EasySax
|
2
|
+
|
3
|
+
EasySax allows you to easily parse large files without the messy syntax needed for working with most Sax parsers. It was inspired after attempting to use [SaxMachine](https://github.com/pauldix/sax-machine) to parse a 500mb XML file that resulted in a huge spike to 2gbs of memory inside a Rails app. EasySax is very lightweight and only stores the element currently being used in memory. It also allows you to access parent elements without storing the whole parent tree in memory. Testing with the same file mentioend above, the memory stayed constant and it processed the file much faster. EasySax is currently used in production at EasyBroker.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'easy_sax'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install easy_sax
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
Given the following test XML
|
23
|
+
```xml
|
24
|
+
<agencies>
|
25
|
+
<agency id="1">
|
26
|
+
<name>Foo</name>
|
27
|
+
<phone>12345678</phone>
|
28
|
+
<properties>
|
29
|
+
<property id="2">
|
30
|
+
<title>Test 2</title>
|
31
|
+
<images>
|
32
|
+
<image url="http://test.com/1.jpg"/>
|
33
|
+
<image url="http://test.com/2.jpg"/>
|
34
|
+
</images>
|
35
|
+
</property>
|
36
|
+
<property id="3">
|
37
|
+
<title>Test 3</title>
|
38
|
+
<images>
|
39
|
+
<image url="http://test.com/4.jpg"/>
|
40
|
+
<image url="http://test.com/5.jpg"/>
|
41
|
+
</images>
|
42
|
+
</property>
|
43
|
+
</properties>
|
44
|
+
</agency>
|
45
|
+
<agency id="2">
|
46
|
+
<name>Bar</name>
|
47
|
+
<properties>
|
48
|
+
<property id="4">
|
49
|
+
<title>Test 4</title>
|
50
|
+
<images>
|
51
|
+
<image url="http://test.com/3.jpg"/>
|
52
|
+
<image url="http://test.com/4.jpg"/>
|
53
|
+
</images>
|
54
|
+
</property>
|
55
|
+
</properties>
|
56
|
+
</agency>
|
57
|
+
</agencies>
|
58
|
+
```
|
59
|
+
You can parse all the property elements with
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
parser = EasySax.parser(File.open('test.xml'))
|
63
|
+
parser.parse_each(:property) do |property|
|
64
|
+
puts "Property id[#{property.attrs[:id]}] title[#{property[:title].text}]"
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
Outputs
|
69
|
+
|
70
|
+
```
|
71
|
+
Property id[2] title[Test 2]
|
72
|
+
Property id[3] title[Test 3]
|
73
|
+
Property id[4] title[Test 4]
|
74
|
+
```
|
75
|
+
|
76
|
+
You can also use the `text_for` method if you prefer to get text elements. `property.text_for(:title)` is the same as `property[:title].text` except it returns nil if the title element doesn't exist.
|
77
|
+
|
78
|
+
If you want to print the property image urls you need to let the parser know that it is an array
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
parser = EasySax.parser(File.open('test.xml'))
|
82
|
+
parser.parse_each(:property, arrays: ['images']) do |property|
|
83
|
+
image_urls = property[:images].map { |image| image.attrs[:url] }
|
84
|
+
puts "Property id[#{property.attrs[:id]}] images#{image_urls}"
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
Outputs
|
89
|
+
|
90
|
+
```
|
91
|
+
Property id[2] images ["http://test.com/1.jpg", "http://test.com/2.jpg"]
|
92
|
+
Property id[3] images ["http://test.com/4.jpg", "http://test.com/5.jpg"]
|
93
|
+
Property id[4] images ["http://test.com/3.jpg", "http://test.com/4.jpg"]
|
94
|
+
```
|
95
|
+
|
96
|
+
Now for something really cool. If you want the root ancestor use the second param in the `parse_each` block
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
parser = EasySax.parser(File.open('test.xml'))
|
100
|
+
parser.parse_each(:property) do |property, ancestor|
|
101
|
+
puts "Property id[#{property.attrs[:id]}] agency id[#{ancestor[:agency].attrs[:id]}]"
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Outputs
|
106
|
+
|
107
|
+
```
|
108
|
+
Property id[2] agency id[1]
|
109
|
+
Property id[3] agency id[1]
|
110
|
+
Property id[4] agency id[2]
|
111
|
+
```
|
112
|
+
|
113
|
+
Now maybe you're lazy like me and don't care about the `agencies` element and want the `agency` to be the oldest ancestor.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
parser = EasySax.parser(File.open('test.xml'))
|
117
|
+
parser.parse_each(:property, ignore: ['agencies']) do |property, ancestor|
|
118
|
+
puts "Property id[#{property.attrs[:id]}] agency id[#{ancestor.attrs[:id]}]"
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
Outputs
|
123
|
+
|
124
|
+
```
|
125
|
+
Property id[2] agency id[1]
|
126
|
+
Property id[3] agency id[1]
|
127
|
+
Property id[4] agency id[2]
|
128
|
+
```
|
129
|
+
|
130
|
+
You can also use `ignore` to speed up the parser by allowing it to know that it doesn't need to keep track of the those elements.
|
131
|
+
## Development
|
132
|
+
|
133
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
134
|
+
|
135
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
|
139
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/easybroker/easy_sax.
|
140
|
+
|
141
|
+
|
142
|
+
## License
|
143
|
+
|
144
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
145
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "easy_sax"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/easy_sax.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'easy_sax/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "easy_sax"
|
8
|
+
spec.version = EasySax::VERSION
|
9
|
+
spec.authors = ["Eric Northam"]
|
10
|
+
spec.email = ["eric@easybroker.com"]
|
11
|
+
|
12
|
+
spec.summary = "A simple SAX parser that enables parsing of large files without the messy syntax of typical SAX parsers."
|
13
|
+
spec.description = "A simple SAX parser that enables parsing of large files without the messy syntax of typical SAX parsers. Currently depends on Nokogiri."
|
14
|
+
spec.homepage = "https://github.com/easybroker/easy_sax"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency "nokogiri", ">= 1.6"
|
23
|
+
spec.add_dependency "activesupport", ">= 1.6"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
28
|
+
spec.add_development_dependency "pry"
|
29
|
+
end
|
data/lib/easy_sax.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'easy_sax/version'
|
2
|
+
require 'easy_sax/parse_error'
|
3
|
+
require 'easy_sax/simple_element'
|
4
|
+
require 'easy_sax/parser'
|
5
|
+
|
6
|
+
# A simple SAX parser that enables parsing of large files without
|
7
|
+
# the messy syntax of typical SAX parsers. Currently depends on
|
8
|
+
# Nokogiri.
|
9
|
+
#
|
10
|
+
# Basic Usage:
|
11
|
+
# EasySax.parser(io).parse_each(target_element, ignore:, array:)
|
12
|
+
# target_element: is the element you want to parse
|
13
|
+
# ignore: are elements that will be ignored and not parsed
|
14
|
+
# arrays: are the elements that should parsed into arrays
|
15
|
+
#
|
16
|
+
# You should use a block which returns the parsed target element
|
17
|
+
# and it's ancestors if it has one.
|
18
|
+
module EasySax
|
19
|
+
def self.parser(io)
|
20
|
+
EasySax::Parser.new(io)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
class EasySax::Parser < Nokogiri::XML::SAX::Document
|
5
|
+
attr_reader :io,
|
6
|
+
:target_element,
|
7
|
+
:callback,
|
8
|
+
:ignorable_elements,
|
9
|
+
:array_elements,
|
10
|
+
:element_stack,
|
11
|
+
:element_text
|
12
|
+
|
13
|
+
def initialize(io)
|
14
|
+
@io = io
|
15
|
+
end
|
16
|
+
|
17
|
+
def parse_each(target_element, ignore: [], arrays: [], &block)
|
18
|
+
validate_array(:arrays, arrays)
|
19
|
+
@target_element = target_element.to_s
|
20
|
+
@ignorable_elements = validate_array(:ignore, ignore)
|
21
|
+
@array_elements = validate_array(:arrays, arrays)
|
22
|
+
@element_stack = []
|
23
|
+
@callback = block
|
24
|
+
Nokogiri::XML::SAX::Parser.new(self).parse(io)
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_element(name, attrs = [])
|
28
|
+
return if ignorable_elements.include?(name)
|
29
|
+
@element_text = ''
|
30
|
+
parent = element_stack.last
|
31
|
+
|
32
|
+
if parent.nil?
|
33
|
+
element_stack << EasySax::SimpleElement.new(name, attrs.to_h)
|
34
|
+
else
|
35
|
+
add_child(parent, name, attrs)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def characters(string)
|
40
|
+
@element_text << string if element_text
|
41
|
+
end
|
42
|
+
|
43
|
+
def cdata_block(string)
|
44
|
+
characters(string)
|
45
|
+
end
|
46
|
+
|
47
|
+
def end_element(name)
|
48
|
+
return if ignorable_elements.include?(name)
|
49
|
+
|
50
|
+
element = element_stack.pop
|
51
|
+
return if element.kind_of?(Array)
|
52
|
+
|
53
|
+
element.text = element_text.strip if element_text.present?
|
54
|
+
callback.call element, element_stack.first if name == target_element
|
55
|
+
end
|
56
|
+
|
57
|
+
def error(string)
|
58
|
+
raise EasySax::ParseError.new(string)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def validate_array(field, array)
|
64
|
+
if array.nil?
|
65
|
+
[]
|
66
|
+
elsif array.kind_of?(Array)
|
67
|
+
array.map { |element| element.to_s }
|
68
|
+
else
|
69
|
+
raise ArgumentError, ("%s must be an Array" % field)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_child(parent, name, attrs)
|
74
|
+
if array_elements.include?(name)
|
75
|
+
parent[name] = []
|
76
|
+
element_stack << parent[name]
|
77
|
+
else
|
78
|
+
element = EasySax::SimpleElement.new(name, attrs.to_h)
|
79
|
+
|
80
|
+
if parent.kind_of?(Array)
|
81
|
+
parent << element
|
82
|
+
elsif name != target_element
|
83
|
+
parent[name] = element
|
84
|
+
end
|
85
|
+
|
86
|
+
element_stack << element
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
|
3
|
+
class EasySax::SimpleElement
|
4
|
+
attr_accessor :name, :attrs, :elements, :text
|
5
|
+
|
6
|
+
def initialize(name, attrs)
|
7
|
+
@name = name
|
8
|
+
@attrs = HashWithIndifferentAccess.new(attrs || {})
|
9
|
+
@elements = HashWithIndifferentAccess.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](key)
|
13
|
+
elements[key]
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(key, value)
|
17
|
+
elements[key] = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def text_for(key)
|
21
|
+
elements[key]&.text
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{}.tap do |hash|
|
26
|
+
hash[:attrs] = attrs unless attrs.empty?
|
27
|
+
hash[:elements] = elements unless elements.empty?
|
28
|
+
hash[:text] = text if text
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :inspect, :to_h
|
33
|
+
alias_method :to_s, :to_h
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: easy_sax
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Northam
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-10-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.12'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: A simple SAX parser that enables parsing of large files without the messy
|
98
|
+
syntax of typical SAX parsers. Currently depends on Nokogiri.
|
99
|
+
email:
|
100
|
+
- eric@easybroker.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/console
|
112
|
+
- bin/setup
|
113
|
+
- easy_sax.gemspec
|
114
|
+
- lib/easy_sax.rb
|
115
|
+
- lib/easy_sax/parse_error.rb
|
116
|
+
- lib/easy_sax/parser.rb
|
117
|
+
- lib/easy_sax/simple_element.rb
|
118
|
+
- lib/easy_sax/version.rb
|
119
|
+
homepage: https://github.com/easybroker/easy_sax
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.5.2.3
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: A simple SAX parser that enables parsing of large files without the messy
|
143
|
+
syntax of typical SAX parsers.
|
144
|
+
test_files: []
|