xpather 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +2 -0
- data/Rakefile +37 -0
- data/ext/xpather/extconf.rb +7 -0
- data/ext/xpather/xpather.c +91 -0
- data/lib/xpather.rb +9 -0
- data/test/books.xml +37 -0
- data/test/xpather_test.rb +9 -0
- metadata +75 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/extensiontask'
|
4
|
+
load 'lib/xpather.rb'
|
5
|
+
|
6
|
+
spec = Gem::Specification.new do |s|
|
7
|
+
s.name = "xpather"
|
8
|
+
s.version = XPather::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Aaron Bedra"]
|
11
|
+
s.email = ["aaron@aaronbedra.com"]
|
12
|
+
s.homepage = "https://github.com/abedra/xpather"
|
13
|
+
s.summary = %q{Quick and painless XPath searching for Ruby}
|
14
|
+
s.description = %q{Quick and painless XPath searching for Ruby using libxml2}
|
15
|
+
|
16
|
+
s.rubyforge_project = "xpather"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
20
|
+
s.require_paths = ["lib", "ext"]
|
21
|
+
s.extensions = %w{ext/xpather/extconf.rb}
|
22
|
+
|
23
|
+
s.add_development_dependency "rake-compiler", "~> 0.7.9"
|
24
|
+
end
|
25
|
+
|
26
|
+
Gem::PackageTask.new(spec) do |pkg|
|
27
|
+
end
|
28
|
+
|
29
|
+
Rake::ExtensionTask.new('xpather', spec)
|
30
|
+
|
31
|
+
Rake::TestTask.new do |t|
|
32
|
+
t.libs << "test"
|
33
|
+
t.test_files = FileList['test/*_test.rb']
|
34
|
+
t.verbose = true
|
35
|
+
end
|
36
|
+
|
37
|
+
task :default => ["compile", "test"]
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
have_library("xml2")
|
3
|
+
find_header("libxml/tree.h", "/usr/include/libxml2")
|
4
|
+
find_header("libxml/parser.h", "/usr/include/libxml2")
|
5
|
+
find_header("libxml/xpath.h", "/usr/include/libxml2")
|
6
|
+
find_header("libxml/xpathInternals.h", "/usr/include/libxml2")
|
7
|
+
create_makefile('xpather')
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#include <ruby/ruby.h>
|
2
|
+
|
3
|
+
#include <libxml/tree.h>
|
4
|
+
#include <libxml/parser.h>
|
5
|
+
#include <libxml/xpath.h>
|
6
|
+
#include <libxml/xpathInternals.h>
|
7
|
+
|
8
|
+
VALUE klass;
|
9
|
+
|
10
|
+
static void xml_free(void *doc) {
|
11
|
+
xmlFreeDoc(doc);
|
12
|
+
}
|
13
|
+
|
14
|
+
VALUE search(VALUE self, VALUE xpathExpr)
|
15
|
+
{
|
16
|
+
VALUE results = rb_ary_new();
|
17
|
+
xmlDocPtr doc;
|
18
|
+
Data_Get_Struct(self, xmlDoc, doc);
|
19
|
+
|
20
|
+
xmlXPathContextPtr xpathCtx;
|
21
|
+
xmlXPathObjectPtr xpathObj;
|
22
|
+
xmlNodeSetPtr nodes;
|
23
|
+
xmlNodePtr cur;
|
24
|
+
int size;
|
25
|
+
int i;
|
26
|
+
|
27
|
+
xpathCtx = xmlXPathNewContext(doc);
|
28
|
+
if (xpathCtx == NULL) {
|
29
|
+
fprintf(stderr, "Error: unable to create new XPath context\n");
|
30
|
+
xmlFreeDoc(doc);
|
31
|
+
return -1;
|
32
|
+
}
|
33
|
+
|
34
|
+
xpathObj = xmlXPathEvalExpression(StringValueCStr(xpathExpr), xpathCtx);
|
35
|
+
if (xpathObj == NULL) {
|
36
|
+
fprintf(stderr, "Error: unable to evaluate xpath expression \"%s\"\n", StringValueCStr(xpathExpr));
|
37
|
+
xmlXPathFreeContext(xpathCtx);
|
38
|
+
xmlFreeDoc(doc);
|
39
|
+
return -1;
|
40
|
+
}
|
41
|
+
|
42
|
+
nodes = xpathObj->nodesetval;
|
43
|
+
size = (nodes) ? nodes->nodeNr : 0;
|
44
|
+
|
45
|
+
for (i = 0; i < size; ++i) {
|
46
|
+
cur = nodes->nodeTab[i];
|
47
|
+
rb_ary_push(results, rb_str_new2(xmlNodeGetContent(cur)));
|
48
|
+
}
|
49
|
+
|
50
|
+
xmlXPathFreeObject(xpathObj);
|
51
|
+
xmlXPathFreeContext(xpathCtx);
|
52
|
+
|
53
|
+
return results;
|
54
|
+
}
|
55
|
+
|
56
|
+
static VALUE initialize(VALUE self, VALUE filename)
|
57
|
+
{
|
58
|
+
rb_iv_set(self, "@filename", filename);
|
59
|
+
return self;
|
60
|
+
}
|
61
|
+
|
62
|
+
static VALUE filename(VALUE self)
|
63
|
+
{
|
64
|
+
return rb_iv_get(self, "@filename");
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE constructor(VALUE self, VALUE filename)
|
68
|
+
{
|
69
|
+
xmlDocPtr doc;
|
70
|
+
VALUE argv[1];
|
71
|
+
|
72
|
+
doc = xmlParseFile(StringValueCStr(filename));
|
73
|
+
if (doc == NULL) {
|
74
|
+
fprintf(stderr, "Error: unable to parse file \"%s\"\n", StringValueCStr(filename));
|
75
|
+
return -1;
|
76
|
+
}
|
77
|
+
|
78
|
+
VALUE t_data = Data_Wrap_Struct(self, 0, xml_free, doc);
|
79
|
+
argv[0] = filename;
|
80
|
+
rb_obj_call_init(t_data, 1, argv);
|
81
|
+
return t_data;
|
82
|
+
}
|
83
|
+
|
84
|
+
void Init_xpather()
|
85
|
+
{
|
86
|
+
klass = rb_define_class("XPather", rb_cObject);
|
87
|
+
rb_define_singleton_method(klass, "new", constructor, 1);
|
88
|
+
rb_define_method(klass, "initialize", initialize, 1);
|
89
|
+
rb_define_method(klass, "filename", filename, 0);
|
90
|
+
rb_define_method(klass, "search", search, 1);
|
91
|
+
}
|
data/lib/xpather.rb
ADDED
data/test/books.xml
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<bookstore>
|
4
|
+
|
5
|
+
<book category="COOKING">
|
6
|
+
<title lang="en">Everyday Italian</title>
|
7
|
+
<author>Giada De Laurentiis</author>
|
8
|
+
<year>2005</year>
|
9
|
+
<price>30.00</price>
|
10
|
+
</book>
|
11
|
+
|
12
|
+
<book category="CHILDREN">
|
13
|
+
<title lang="en">Harry Potter</title>
|
14
|
+
<author>J K. Rowling</author>
|
15
|
+
<year>2005</year>
|
16
|
+
<price>29.99</price>
|
17
|
+
</book>
|
18
|
+
|
19
|
+
<book category="WEB">
|
20
|
+
<title lang="en">XQuery Kick Start</title>
|
21
|
+
<author>James McGovern</author>
|
22
|
+
<author>Per Bothner</author>
|
23
|
+
<author>Kurt Cagle</author>
|
24
|
+
<author>James Linn</author>
|
25
|
+
<author>Vaidyanathan Nagarajan</author>
|
26
|
+
<year>2003</year>
|
27
|
+
<price>49.99</price>
|
28
|
+
</book>
|
29
|
+
|
30
|
+
<book category="WEB">
|
31
|
+
<title lang="en">Learning XML</title>
|
32
|
+
<author>Erik T. Ray</author>
|
33
|
+
<year>2003</year>
|
34
|
+
<price>39.95</price>
|
35
|
+
</book>
|
36
|
+
|
37
|
+
</bookstore>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'xpather/xpather'
|
3
|
+
|
4
|
+
class TestXPather < MiniTest::Unit::TestCase
|
5
|
+
def test_basic_search
|
6
|
+
document = XPather.new("test/books.xml")
|
7
|
+
assert_equal ["Giada De Laurentiis"], document.search("/bookstore/book[1]/author")
|
8
|
+
end
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xpather
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Aaron Bedra
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-09-04 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rake-compiler
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.7.9
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
description: Quick and painless XPath searching for Ruby using libxml2
|
28
|
+
email:
|
29
|
+
- aaron@aaronbedra.com
|
30
|
+
executables: []
|
31
|
+
|
32
|
+
extensions:
|
33
|
+
- ext/xpather/extconf.rb
|
34
|
+
extra_rdoc_files: []
|
35
|
+
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- Rakefile
|
40
|
+
- ext/xpather/extconf.rb
|
41
|
+
- ext/xpather/xpather.c
|
42
|
+
- lib/xpather.rb
|
43
|
+
- test/books.xml
|
44
|
+
- test/xpather_test.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: https://github.com/abedra/xpather
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
- ext
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project: xpather
|
70
|
+
rubygems_version: 1.6.2
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Quick and painless XPath searching for Ruby
|
74
|
+
test_files: []
|
75
|
+
|