vtd-xml 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/fixtures
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format progress
2
+ --order random
3
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vtd-xml.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 James Conroy-Finn
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,88 @@
1
+ # vtd-xml
2
+
3
+ Parse large amounts of XML quickly and easily.
4
+
5
+ **This library currently only works with JRuby.**
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'vtd-xml', '~> 0.0.1'
12
+
13
+ And then execute:
14
+
15
+ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ gem install vtd-xml
20
+
21
+ ## Usage
22
+
23
+ With the following example XML:
24
+
25
+ ``` xml
26
+ <?xml version="1.0" encoding="utf-8"?>
27
+ <books>
28
+ <book title="A Tale of Two Cities" sold="200000000" firstPublished="1859">
29
+ <author name="Charles Dickens" />
30
+ </book>
31
+ <book title="The Lord of the Rings" sold="150000000" firstPublished="1954">
32
+ <author name="J. R. R. Tolkien" />
33
+ </book>
34
+ <book title="The Little Prince" sold="140000000" firstPublished="1943">
35
+ <author name="Antoine de Saint-Exupéry" />
36
+ </book>
37
+ </books>
38
+ ```
39
+
40
+ ### Parsing a file
41
+
42
+ ``` ruby
43
+ require 'vtd-xml'
44
+
45
+ # Create a parser
46
+ parser = VTD::Xml::Parser.new 'path/to.xml'
47
+
48
+ # This shortcut does the same
49
+ parser = VTD::Xml.open 'path/to.xml'
50
+
51
+ parser.find('//book/author').each do |node|
52
+ # Iterates through each node
53
+ end
54
+
55
+ parser.find('//book/author').max_by { |node| node['sold'] }
56
+ ```
57
+
58
+ ### Finding a node
59
+
60
+ ``` ruby
61
+ node = parser.find('//book/author[1]').first
62
+ ```
63
+
64
+ ### Working with attributes
65
+
66
+ ``` ruby
67
+
68
+ # Accessing attributes
69
+ node['name']
70
+
71
+ node.fetch('missing', 'so use this default')
72
+ node.fetch('another-missing') { 'so call this block and use it' }
73
+
74
+ node.slice('title', 'missing')
75
+ # => {'title' => 'A Tale of Two Cities', 'missing' => nil}
76
+
77
+ node.attributes # => returns every attribute
78
+ ```
79
+
80
+ **See the examples directory for more.**
81
+
82
+ ## Contributing
83
+
84
+ 1. Fork it
85
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 4. Push to the branch (`git push origin my-new-feature`)
88
+ 5. Create new Pull Request
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ $: << 'lib'
3
+
4
+ Rake.add_rakelib 'tasks'
5
+
6
+ desc 'Run RSpec code examples'
7
+ task :default => :spec
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby --profile.flat
2
+ require 'java'
3
+
4
+ $: << 'lib'
5
+ require 'vtd-xml-java.jar'
6
+
7
+ vg = com.ximpleware.VTDGen.new
8
+ vg.parse_file('spec/fixtures/books.xml', false)
9
+
10
+ nav = vg.get_nav
11
+ auto_pilot = com.ximpleware.AutoPilot.new(nav)
12
+ auto_pilot.selectXPath('//book/author')
13
+
14
+ while auto_pilot.eval_xpath != -1
15
+ name = nav.get_attr_val('name')
16
+ if name != -1
17
+ puts nav.to_normalized_string(name)
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby --profile.flat
2
+ require 'nokogiri'
3
+
4
+ doc = Nokogiri::XML(File.open('spec/fixtures/products.xml'))
5
+
6
+ count = odds = 0
7
+
8
+ doc.xpath('//outer/inner').each do |node|
9
+ count += 1
10
+ odds += 1 if node['id'].to_i.odd?
11
+ end
12
+
13
+ puts "That's #{odds} odd IDs in #{count} nodes!"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby --profile.flat
2
+
3
+ $: << 'lib'
4
+ require 'vtd/xml'
5
+
6
+ xml = VTD::Xml.open('spec/fixtures/books.xml')
7
+
8
+ # Make use of the entire attribute list
9
+ node = xml.find('//book').max_by { |node| node.attributes['sold'].to_i }
10
+ puts "Max sold was #{node.attributes['sold'].inspect}"
11
+
12
+ # Make use of the attribute cache
13
+ node = xml.find('//book').max_by { |node| node['sold'].to_i }
14
+ puts "Max sold was #{node['sold'].inspect}"
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby --profile.flat
2
+
3
+ $: << 'lib'
4
+ require 'vtd/xml'
5
+
6
+ xml = VTD::Xml.open('spec/fixtures/products.xml')
7
+
8
+ count = odds = 0
9
+
10
+ xml.find('//outer/inner').each do |node|
11
+ count += 1
12
+ odds += 1 if node['id'].to_i.odd?
13
+ end
14
+
15
+ puts "That's #{odds} odd IDs in #{count} nodes!"
Binary file
@@ -0,0 +1 @@
1
+ require 'vtd/xml'
@@ -0,0 +1,15 @@
1
+ require 'java'
2
+ require 'vtd-xml-java.jar'
3
+
4
+ require 'vtd/xml/version'
5
+ require 'vtd/xml/finder'
6
+ require 'vtd/xml/parser'
7
+ require 'vtd/xml/node'
8
+
9
+ module VTD
10
+ module Xml
11
+ def self.open(path)
12
+ Parser.new(path)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module VTD
2
+ module Xml
3
+ class Finder
4
+ include Enumerable
5
+
6
+ def initialize(nav, xpath)
7
+ @nav = nav
8
+ @xpath = xpath
9
+
10
+ @auto_pilot = com.ximpleware.AutoPilot.new(@nav)
11
+ @auto_pilot.select_xpath(@xpath)
12
+ end
13
+
14
+ def each
15
+ while (current = @auto_pilot.eval_xpath) != -1
16
+ yield Node.new(@nav, @auto_pilot, current)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ module VTD
3
+ module Xml
4
+ class Generator
5
+ GENERATORS = [:products, :books]
6
+
7
+ def initialize(root)
8
+ @root = root
9
+ end
10
+
11
+ def generate
12
+ GENERATORS.each do |generator_name|
13
+ open(generator_name, &method(generator_name))
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def open(generator_name, &writer)
20
+ File.open(fixture_path(generator_name), 'w', &writer)
21
+ end
22
+
23
+ def fixture_path(generator_name)
24
+ File.join(@root, "#{generator_name}.xml")
25
+ end
26
+
27
+ def products(f)
28
+ f.puts '<?xml version="1.0" encoding="utf-8"?>'
29
+ f.puts '<container>'
30
+
31
+ 1_000_000.times do |i|
32
+ f.puts %( <outer id="#{i + 10}">)
33
+ f.puts %( <inner id="#{i}" name="Could be random #{i}" />)
34
+ f.puts %( </outer>)
35
+ end
36
+
37
+ f.puts '</container>'
38
+ end
39
+
40
+ def books(f)
41
+ f.puts \
42
+ '<?xml version="1.0" encoding="utf-8"?>',
43
+ '<books>',
44
+ ' <book title="A Tale of Two Cities" sold="200000000" firstPublished="1859">',
45
+ ' <author name="Charles Dickens" />',
46
+ ' </book>',
47
+ ' <book title="The Lord of the Rings" sold="150000000" firstPublished="1954">',
48
+ ' <author name="J. R. R. Tolkien" />',
49
+ ' </book>',
50
+ ' <book title="The Little Prince" sold="140000000" firstPublished="1943">',
51
+ ' <author name="Antoine de Saint-Exupéry" />',
52
+ ' </book>',
53
+ '</books>'
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,32 @@
1
+ require 'vtd/xml/node/attributes'
2
+
3
+ module VTD
4
+ module Xml
5
+ class Node
6
+ include Attributes
7
+
8
+ attr_reader :name, :text
9
+
10
+ def initialize(nav, auto_pilot, current)
11
+ @nav = nav
12
+ @auto_pilot = auto_pilot
13
+ @current = current
14
+ super
15
+ end
16
+
17
+ def name
18
+ @name ||= @nav.to_string(@current)
19
+ end
20
+
21
+ def text
22
+ @text ||= string_from_index @nav.get_text
23
+ end
24
+
25
+ private
26
+
27
+ def string_from_index(index)
28
+ @nav.to_normalized_string(index) if index != -1
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,57 @@
1
+ module VTD
2
+ module Xml
3
+ class Node
4
+ module Attributes
5
+ AttributeMissing = Class.new(StandardError)
6
+
7
+ def initialize(*)
8
+ @attribute_cache = {}
9
+ @attributes = nil
10
+ end
11
+
12
+ def attributes
13
+ return @attributes if @attributes
14
+
15
+ @attributes = {}
16
+
17
+ @auto_pilot.select_attr('*')
18
+ while (i = @auto_pilot.iterate_attr) != -1
19
+ @attributes[string_from_index i] = string_from_index i + 1
20
+ end
21
+
22
+ @attribute_cache = @attributes
23
+ end
24
+
25
+ def [](key)
26
+ find_attribute(key)
27
+ end
28
+
29
+ def slice(*keys)
30
+ Hash[*keys.flat_map { |key| [key, find_attribute(key)] }]
31
+ end
32
+
33
+ def fetch(*args)
34
+ if args.length == 2
35
+ key, default = *args
36
+ else
37
+ key = args.first
38
+ end
39
+
40
+ if item = find_attribute(key)
41
+ return item
42
+ end
43
+
44
+ return yield(key) if block_given?
45
+ return default if defined? default
46
+ raise AttributeMissing, 'attribute not found'
47
+ end
48
+
49
+ private
50
+
51
+ def find_attribute(key)
52
+ @attribute_cache[key] ||= string_from_index @nav.get_attr_val(key)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,16 @@
1
+ module VTD
2
+ module Xml
3
+ class Parser
4
+ def initialize(path)
5
+ @path = path
6
+
7
+ @gen = com.ximpleware.VTDGen.new
8
+ @gen.parse_file(@path, false)
9
+ end
10
+
11
+ def find(xpath)
12
+ VTD::Xml::Finder.new(@gen.get_nav, xpath).enum_for(:each)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module VTD
2
+ module Xml
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,2 @@
1
+ $: << 'lib'
2
+ require 'vtd/xml'
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe VTD::Xml::Parser do
4
+ let(:parser) { VTD::Xml::Parser.new 'spec/fixtures/books.xml' }
5
+
6
+ it 'will pull everything that matches your XPath' do
7
+ expect(parser.find('//book/author').to_a.length).to eq(3)
8
+ end
9
+
10
+ it 'yields a node for each match' do
11
+ parser.find('//book/author').with_index do |node, index|
12
+ expect(node.name).to eq('author')
13
+ expect(node.text).to be_nil
14
+ end
15
+ end
16
+
17
+ describe 'node attributes' do
18
+ let(:book) { parser.find('//book[1]').first }
19
+ let(:title) { 'A Tale of Two Cities' }
20
+ let(:sold) { '200000000' }
21
+ let(:published) { '1859' }
22
+
23
+ it 'can be accessed with []' do
24
+ expect(book['title']).to eq(title)
25
+ end
26
+
27
+ it 'can be accessed with fetch' do
28
+ expect(book.fetch('title')).to eq(title)
29
+ end
30
+
31
+ it 'uses the second argument when fetch fails' do
32
+ expect(book.fetch('not-present', 'Arg')).to eq('Arg')
33
+ end
34
+
35
+ it 'uses a block when fetch fails' do
36
+ expect(book.fetch('not-present') { 'Block' }).to eq('Block')
37
+ end
38
+
39
+ it 'can slice attributes' do
40
+ expect(book.slice('title', 'sold')).to eq(
41
+ 'title' => title, 'sold' => sold)
42
+ end
43
+
44
+ it 'can return all attributes' do
45
+ expect(book.attributes).to eq(
46
+ 'title' => title, 'sold' => sold, 'firstPublished' => published)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe VTD::Xml do
4
+ it 'has a version number' do
5
+ VTD::Xml::VERSION.should_not be_nil
6
+ end
7
+
8
+ describe '.open' do
9
+ it 'creates a new parser' do
10
+ VTD::Xml::Parser.should_receive(:new).with('path.xml')
11
+ VTD::Xml.open 'path.xml'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ namespace :fixtures do
2
+ desc 'Generate XML fixtures for tests'
3
+ task :generate do
4
+ require 'vtd/xml/generator'
5
+
6
+ root = File.expand_path '../../spec/fixtures', __FILE__
7
+ VTD::Xml::Generator.new(root).generate
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new do |t|
4
+ t.rspec_opts = '--format progress --color --order random'
5
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ $: << 'lib'
3
+ require 'vtd/xml/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'vtd-xml'
7
+ gem.version = VTD::Xml::VERSION
8
+ gem.platform = 'java'
9
+
10
+ gem.authors = ['James Conroy-Finn']
11
+ gem.email = ['james@logi.cl']
12
+
13
+ gem.description = %q{VTD-XML for JRuby}
14
+ gem.summary = %q{A thin wrapper around the VTD-XML Java library}
15
+ gem.homepage = 'https://github.com/jcf/vtd-xml'
16
+ gem.license = 'MIT'
17
+
18
+ gem.files = `git ls-files`.split("\n")
19
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(spec|features)/})
21
+ gem.require_paths = ['lib']
22
+
23
+ gem.add_development_dependency 'rake'
24
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vtd-xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: java
7
+ authors:
8
+ - James Conroy-Finn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: !binary |-
21
+ MA==
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: !binary |-
28
+ MA==
29
+ none: false
30
+ prerelease: false
31
+ type: :development
32
+ description: VTD-XML for JRuby
33
+ email:
34
+ - james@logi.cl
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - ".gitignore"
40
+ - ".rspec"
41
+ - Gemfile
42
+ - LICENSE.txt
43
+ - README.md
44
+ - Rakefile
45
+ - benchmarks/jruby_vtd.rb
46
+ - benchmarks/nokogiri.rb
47
+ - examples/enumerable.rb
48
+ - examples/simple.rb
49
+ - lib/vtd-xml-java.jar
50
+ - lib/vtd-xml.rb
51
+ - lib/vtd/xml.rb
52
+ - lib/vtd/xml/finder.rb
53
+ - lib/vtd/xml/generator.rb
54
+ - lib/vtd/xml/node.rb
55
+ - lib/vtd/xml/node/attributes.rb
56
+ - lib/vtd/xml/parser.rb
57
+ - lib/vtd/xml/version.rb
58
+ - spec/spec_helper.rb
59
+ - spec/vtd/xml/parser_spec.rb
60
+ - spec/vtd/xml_spec.rb
61
+ - tasks/fixtures.rake
62
+ - tasks/rspec.rake
63
+ - vtd-xml.gemspec
64
+ homepage: https://github.com/jcf/vtd-xml
65
+ licenses:
66
+ - MIT
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: !binary |-
76
+ MA==
77
+ none: false
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: !binary |-
83
+ MA==
84
+ none: false
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 1.8.24
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: A thin wrapper around the VTD-XML Java library
91
+ test_files:
92
+ - spec/spec_helper.rb
93
+ - spec/vtd/xml/parser_spec.rb
94
+ - spec/vtd/xml_spec.rb