traverse 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in traversable.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Traverse
2
+
3
+ Traverse is a simple tool that makes it easy to traverse XML.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'run the spec'
4
+ task "spec" do
5
+ load './spec/spec.rb'
6
+ end
@@ -0,0 +1,3 @@
1
+ module Traverse
2
+ VERSION = "0.0.1"
3
+ end
data/lib/traverse.rb ADDED
@@ -0,0 +1,69 @@
1
+ require "traverse/version"
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+
5
+ module Traverse
6
+ class Document
7
+ def initialize document
8
+ if document.is_a? String
9
+ begin
10
+ @document = Nokogiri::XML(document)
11
+ rescue
12
+ return nil
13
+ end
14
+ else
15
+ @document = document
16
+ end
17
+
18
+ if text_node?
19
+ define_singleton_method "text" do
20
+ @document.children.first.content
21
+ end
22
+ else
23
+ @document.children.reject do |child|
24
+ child.is_a? Nokogiri::XML::Text
25
+ end.group_by(&:name).each do |name, children|
26
+ if children.count == 1
27
+ define_singleton_method "#{name}" do
28
+ Document.new children.first
29
+ end
30
+ else
31
+ define_singleton_method "#{name}s" do
32
+ children.map { |child| Document.new child }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def [] attr
40
+ @document.get_attribute attr
41
+ end
42
+
43
+ private
44
+ def method_missing m, *args, &block
45
+ self[m] or super
46
+ end
47
+
48
+ def text_node?
49
+ num_children = @document.children.count
50
+ return false unless num_children == 1
51
+
52
+ @document.children.first.is_a? Nokogiri::XML::Text
53
+ end
54
+ end
55
+
56
+ module Proxy
57
+ private
58
+ def proxy *args
59
+ if args.empty?
60
+ @proxy
61
+ else
62
+ @proxy = args.first
63
+ def method_missing m
64
+ @proxy.send m
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
data/spec/spec.rb ADDED
@@ -0,0 +1,91 @@
1
+ $:.push '../'
2
+ require 'traverse'
3
+
4
+ gem 'minitest'
5
+ require 'minitest/autorun'
6
+ require 'minitest/pride'
7
+
8
+ xml = %{
9
+ <book title="Vineland" author="Thomas Pynchon">
10
+ <author name="Thomas Pynchon">
11
+ <book title="V" />
12
+ <book title="The Crying of Lot 49" />
13
+ <book title="Gravity's Rainbow" />
14
+ <book title="Slow Learner" />
15
+ <book title="Vineland" />
16
+ <book title="Mason &amp; Dixon" />
17
+ <book title="Against the Day" />
18
+ <book title="Inherent Vice" />
19
+ </author>
20
+ <epigraph author="Johnny Copeland">
21
+ Every dog has his day,
22
+ and a good dog
23
+ just might have two days.
24
+ </epigraph>
25
+ <quotations>
26
+ <quotation>
27
+ Up and down that street, she remembered, television screens had
28
+ flickered silent blue in the darkness. Strange loud birds, not of the
29
+ neighborhood, were attracted, some content to perch in the palm
30
+ trees, keeping silence and an eye out for the rats who lived in the
31
+ fronds, others flying by close to windows, seeking an angle to sit
32
+ and view the picture from. When the commercials came on, the birds,
33
+ with voices otherworldly pure, would sing back at them, sometimes
34
+ even when none were on.
35
+ </quotation>
36
+ <quotation>
37
+ Takeshi recognized his acquaintance Minoru, a government bomb-squad
38
+ expert. Not a genius, exactly, more like an idiot savant with X-ray
39
+ vision.
40
+ </quotation>
41
+ </quotes>
42
+ <review reviewer="Salman Rushdie">
43
+ What is interesting is to have before us, at the end of the Greed
44
+ Decade, that rarest of birds: a major political novel about what
45
+ America has been doing to itself, to its children, all these many
46
+ years.
47
+ </review>
48
+ <text text="seriously, who writes XML like this">
49
+ I mean, rilly.
50
+ </text>
51
+ </book>
52
+ }
53
+
54
+ describe Traverse::Document do
55
+ before do
56
+ @doc = Traverse::Document.new xml
57
+ end
58
+
59
+ it "helps you access attributes" do
60
+ @doc.book.title.must_equal "Vineland"
61
+ end
62
+
63
+ it "also helps you access attributes shadowed by children" do
64
+ @doc.book.author.wont_equal "Thomas Pynchon"
65
+ @doc.book['author'].must_equal "Thomas Pynchon"
66
+ @doc.book.author.name.must_equal "Thomas Pynchon"
67
+ end
68
+
69
+ it "helps you get at child nodes" do
70
+ @doc.book.review.reviewer.must_equal "Salman Rushdie"
71
+ @doc.book.epigraph.author.must_equal "Johnny Copeland"
72
+ end
73
+
74
+ it "knows when a node contains only text" do
75
+ assert @doc.book.epigraph.send(:text_node?)
76
+ end
77
+
78
+ it "handles annoying text nodes transparently" do
79
+ @doc.book.epigraph.text.must_match(/Every dog has his day/)
80
+ @doc.book.review.text.must_match(/that rarest of birds/)
81
+ end
82
+
83
+ it "nevertheless handles attributes named 'text'" do
84
+ @doc.book.text['text'].must_match(/seriously/)
85
+ @doc.book.text.text.must_match(/rilly/)
86
+ end
87
+
88
+ it "knows to collect children with the same name" do
89
+ @doc.book.author.books.count.must_equal 8
90
+ end
91
+ end
data/traverse.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "traverse/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "traverse"
7
+ s.version = Traverse::VERSION
8
+ s.authors = ["happy4crazy"]
9
+ s.email = ["alan.m.odonnell@gmail.com"]
10
+ s.homepage = "https://github.com/happy4crazy/traverse"
11
+ s.summary = %q{Easily traverse an XML document.}
12
+ s.description = %q{Easily traverse an XML document.}
13
+
14
+ s.rubyforge_project = "traverse"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'nokogiri', '~> 1.5'
22
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: traverse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - happy4crazy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-02 00:00:00.000000000 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: &2164471840 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2164471840
26
+ description: Easily traverse an XML document.
27
+ email:
28
+ - alan.m.odonnell@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - lib/traverse.rb
38
+ - lib/traverse/version.rb
39
+ - spec/spec.rb
40
+ - traverse.gemspec
41
+ has_rdoc: true
42
+ homepage: https://github.com/happy4crazy/traverse
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project: traverse
62
+ rubygems_version: 1.6.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Easily traverse an XML document.
66
+ test_files:
67
+ - spec/spec.rb