rasantiago-tiny_xpath_helper 0.1.0

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/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = TinyXPathHelper
2
+
3
+ == Description
4
+
5
+ Very light syntax for using XPaths on XML documents or REXML nodes
6
+
7
+ == Examples
8
+
9
+ TinyXPathHelper.new takes one parameter: an XML document (as a string or IO) or a REXML element
10
+ >> xpath = TinyXPathHelper.new( File.open( 'test/xml/sample.xml' ) )
11
+
12
+ Then, to find the string values of matching nodes, there's a super-light syntax:
13
+ >> xpath[ 'node/' ]
14
+ => ["one", "two", "three\n "]
15
+
16
+ It works on attributes, too
17
+ >> xpath[ 'node/@style' ]
18
+ => ["first"]
19
+
20
+ If you prefer, you can use #all instead of square brackets
21
+ >> xpath.all( 'node/@style' )
22
+ => ["first"]
23
+
24
+ If you just want the first match, use #first
25
+ >> xpath.first( 'node/' )
26
+ => "one"
27
+
28
+ A slightly more elaborate API is available as #find_xpath
29
+ >> xpath.find_xpath( 'node/@style', :format => :xml, :find => :first )
30
+ => style='first'
31
+
32
+ Where :format can be :text (returns a string), or :xml (returns a REXML element),
33
+ and :find can be :first or :all
34
+
35
+ >> xpath.find_xpath( 'node/@style', :format => :xml, :find => :all )
36
+ => [style='first']
37
+
38
+ The output from :format => :xml is suitable for passing to another TinyXPathHelper
39
+ >> node_tree = xpath.find_xpath( 'node/three', :format => :xml )
40
+ >> deeper_xpath = TinyXPathHelper.new( node_tree )
41
+ >> deeper_xpath[ 'b/@beta' ]
42
+ => ["true"]
43
+
44
+ --
45
+ doctest_require: 'lib/tiny_xpath_helper.rb'
46
+ ++
47
+
48
+ Copyright (c) 2009 raSANTIAGO + Associates LLC
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the tiny_xpath_helper plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the tiny_xpath_helper plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'TinyXPathHelper'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), "lib", "tiny_path_helper")
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,97 @@
1
+ require 'rexml/document'
2
+
3
+ class TinyXPathHelper
4
+ attr :node
5
+
6
+ def initialize(xml)
7
+ @xml = xml
8
+ @node = self.class.xml_node_for_xmlish(xml)
9
+ end
10
+
11
+ def find_xpath(xpath_expr, options = {})
12
+ self.class.find_xpath_from( node, xpath_expr, options )
13
+ end
14
+
15
+ alias at find_xpath
16
+
17
+ def first(xpath_expr, options = {})
18
+ self.find_xpath( xpath_expr, options.update(:find => :first) )
19
+ end
20
+
21
+ def all(xpath_expr, options = {})
22
+ self.find_xpath( xpath_expr, options.update(:find => :all) )
23
+ end
24
+ alias [] all
25
+
26
+ def self.io_stream_classes
27
+ [ IOStream ] rescue [ IO, StringIO ] # thoughtbot-paperclip fixes the ducktype mess here
28
+ end
29
+
30
+ def self.classes_that_are_xmlish
31
+ io_stream_classes + [ String, REXML::Document ]
32
+ end
33
+
34
+ def self.xml_node_for_xmlish( xml )
35
+ if io_stream_classes.any?{|k| k === xml }
36
+ xml = xml.read
37
+ end
38
+ if String === xml
39
+ xml = REXML::Document.new(xml)
40
+ end
41
+ if REXML::Document === xml
42
+ xml = xml.root
43
+ end
44
+ if not REXML::Element === xml
45
+ raise TypeError.new("Expected REXML::Element, got #{xml.class}")
46
+ end
47
+ return xml
48
+ end
49
+
50
+ def self.xml_node_to_text(node)
51
+ if(node.respond_to? :text)
52
+ # XML::Elements don't to_s in the way we want
53
+ val = node.text
54
+ else
55
+ val = node.to_s
56
+ end
57
+ end
58
+
59
+ def self.find_xpath_from(element, path, options = {}, &blk)
60
+
61
+ format = options[:format] || :text
62
+ if format == :array
63
+ options.update( :format => :text, :find => :all )
64
+ end
65
+
66
+ count = options[:find] || :first
67
+
68
+ if format == :text
69
+ filter = lambda{|node| node && xml_node_to_text(node) }
70
+ elsif format == :xml
71
+ filter = lambda{|node| node }
72
+ else
73
+ raise "I don't know the format #{format.inspect}"
74
+ end
75
+
76
+ if count == :all
77
+ val = REXML::XPath.match(element, path).map do |node|
78
+ filter.call( node )
79
+ end
80
+ elsif count == :first
81
+ val = filter.call(
82
+ REXML::XPath.first(element, path)
83
+ )
84
+ else
85
+ raise "I don't know how to find #{count.inspect}"
86
+ end
87
+
88
+ if(blk)
89
+ return val if val == nil or val == []
90
+ return blk.call(val)
91
+ end
92
+ return val
93
+ end
94
+
95
+ end
96
+
97
+ TinyXpathHelper = TinyXPathHelper
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :tiny_xpath_helper do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
4
+ require 'test/unit'
5
+ require 'tiny_xpath_helper.rb'
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class TinyXPathHelperTest < ActiveSupport::TestCase
4
+ test "find first returns nil if there is no match" do
5
+ xpath = TinyXPathHelper.new("<xml/>")
6
+ assert xpath.first('*').nil?
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ <xml>
2
+ <node style="first">one</node>
3
+ <node>two</node>
4
+ <node>three
5
+ <three>
6
+ <a/><b beta="true"/><c/>
7
+ </three>
8
+ </node>
9
+ </xml>
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{tiny_xpath_helper}
5
+ s.version = "0.1.0"
6
+
7
+ s.authors = ["Jesse Wolfe"]
8
+ s.date = %q{2009-06-01}
9
+ s.description = %q{Very light syntax for using XPaths on XML documents or REXML nodes}
10
+ s.email = %q{jesse@rasantiago.com}
11
+ s.files = %w[ uninstall.rb init.rb Rakefile lib/tiny_xpath_helper.rb tiny_xpath_helper.gemspec README.rdoc tasks/tiny_xpath_helper_tasks.rake install.rb test/tiny_xpath_helper_test.rb test/xml test/xml/sample.xml test/test_helper.rb ]
12
+ s.has_rdoc = false
13
+ s.homepage = %q{http://github.com/rasantiago/tiny_xpath_helper}
14
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.3.1}
17
+ s.summary = %q{Very light syntax for using XPaths on XML documents or REXML nodes}
18
+ end
19
+
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rasantiago-tiny_xpath_helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jesse Wolfe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Very light syntax for using XPaths on XML documents or REXML nodes
17
+ email: jesse@rasantiago.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - uninstall.rb
26
+ - init.rb
27
+ - Rakefile
28
+ - lib/tiny_xpath_helper.rb
29
+ - tiny_xpath_helper.gemspec
30
+ - README.rdoc
31
+ - tasks/tiny_xpath_helper_tasks.rake
32
+ - install.rb
33
+ - test/tiny_xpath_helper_test.rb
34
+ - test/xml
35
+ - test/xml/sample.xml
36
+ - test/test_helper.rb
37
+ has_rdoc: false
38
+ homepage: http://github.com/rasantiago/tiny_xpath_helper
39
+ post_install_message:
40
+ rdoc_options:
41
+ - --inline-source
42
+ - --charset=UTF-8
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.2.0
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Very light syntax for using XPaths on XML documents or REXML nodes
64
+ test_files: []
65
+