xpather 0.0.1
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/.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
|
+
|