blackwinter-ruby-xquery 0.2.2
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/COPYING +676 -0
- data/ChangeLog +5 -0
- data/README +41 -0
- data/Rakefile +21 -0
- data/lib/libxml/xquery/enhanced_find.rb +49 -0
- data/lib/libxml/xquery/namespaces.rb +67 -0
- data/lib/libxml/xquery/string_representation.rb +49 -0
- data/lib/libxml/xquery/uniqueness.rb +92 -0
- data/lib/libxml/xquery/version.rb +35 -0
- data/lib/libxml/xquery.rb +45 -0
- data/lib/xml/xquery.rb +2 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/xquery_spec.rb +47 -0
- data/test_data/hamlet.xml +9151 -0
- data/test_data/play.dtd +27 -0
- metadata +85 -0
data/README
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
= ruby-xquery - Libxml's XPath support + plain ol' Ruby = XQuery (kind of... ;-)
|
2
|
+
|
3
|
+
== VERSION
|
4
|
+
|
5
|
+
This documentation refers to ruby-xquery version 0.2.2
|
6
|
+
|
7
|
+
|
8
|
+
== DESCRIPTION
|
9
|
+
|
10
|
+
TODO: well, the description... ;-)
|
11
|
+
|
12
|
+
|
13
|
+
== LINKS
|
14
|
+
|
15
|
+
<b></b>
|
16
|
+
Documentation:: <http://prometheus.rubyforge.org/ruby-xquery>
|
17
|
+
Source code (old):: <http://prometheus.rubyforge.org/svn/scratch/ruby-xquery>
|
18
|
+
Source code:: <http://github.com/blackwinter/ruby-xquery>
|
19
|
+
Rubyforge project:: <http://rubyforge.org/projects/prometheus>
|
20
|
+
|
21
|
+
|
22
|
+
== AUTHORS
|
23
|
+
|
24
|
+
* Jens Wille <mailto:jens.wille@uni-koeln.de>
|
25
|
+
|
26
|
+
|
27
|
+
== LICENSE AND COPYRIGHT
|
28
|
+
|
29
|
+
Copyright (C) 2007-2008 Jens Wille
|
30
|
+
|
31
|
+
ruby-xquery is free software: you can redistribute it and/or modify it under
|
32
|
+
the terms of the GNU General Public License as published by the Free Software
|
33
|
+
Foundation, either version 3 of the License, or (at your option) any later
|
34
|
+
version.
|
35
|
+
|
36
|
+
ruby-xquery is distributed in the hope that it will be useful, but WITHOUT ANY
|
37
|
+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
38
|
+
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
39
|
+
|
40
|
+
You should have received a copy of the GNU General Public License along with
|
41
|
+
ruby-xquery. If not, see <http://www.gnu.org/licenses/>.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'hen'
|
3
|
+
rescue LoadError
|
4
|
+
abort "Please install the 'hen' gem first."
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'lib/libxml/xquery/version'
|
8
|
+
|
9
|
+
Hen.lay! {{
|
10
|
+
:rubyforge => {
|
11
|
+
:package => 'ruby-xquery'
|
12
|
+
},
|
13
|
+
|
14
|
+
:gem => {
|
15
|
+
:version => LibXML::XML::XQuery::VERSION,
|
16
|
+
:summary => "Libxml's XPath support + plain ol' Ruby = XQuery (kind of... ;-)",
|
17
|
+
:files => FileList['lib/**/*.rb'].to_a,
|
18
|
+
:extra_files => FileList['[A-Z]*', 'spec/**/*.rb', 'test_data/**/*'].to_a,
|
19
|
+
:dependencies => [['libxml-ruby', '>= 0.9.3']]
|
20
|
+
}
|
21
|
+
}}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-xquery, mimicking XQuery in Ruby. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
10
|
+
# #
|
11
|
+
# ruby-xquery is free software; you can redistribute it and/or modify it #
|
12
|
+
# under the terms of the GNU General Public License as published by the Free #
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
14
|
+
# any later version. #
|
15
|
+
# #
|
16
|
+
# ruby-xquery is distributed in the hope that it will be useful, but WITHOUT #
|
17
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
19
|
+
# more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU General Public License along #
|
22
|
+
# with ruby-xquery. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
module LibXML::XML::XQuery::EnhancedFind
|
28
|
+
|
29
|
+
def enhanced_find(xpath)
|
30
|
+
find(xpath.gsub(/\*\*/, 'descendant::node()'), namespaces)
|
31
|
+
end
|
32
|
+
alias_method :[], :enhanced_find
|
33
|
+
|
34
|
+
def /(xpath)
|
35
|
+
enhanced_find(xpath.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.included(base)
|
39
|
+
# overwrite original methods
|
40
|
+
instance_methods.each { |method|
|
41
|
+
base.send(:define_method, method, instance_method(method))
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
[LibXML::XML::Document, LibXML::XML::Node].each { |klass|
|
48
|
+
klass.send :include, LibXML::XML::XQuery::EnhancedFind
|
49
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-xquery, mimicking XQuery in Ruby. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
10
|
+
# #
|
11
|
+
# ruby-xquery is free software; you can redistribute it and/or modify it #
|
12
|
+
# under the terms of the GNU General Public License as published by the Free #
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
14
|
+
# any later version. #
|
15
|
+
# #
|
16
|
+
# ruby-xquery is distributed in the hope that it will be useful, but WITHOUT #
|
17
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
19
|
+
# more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU General Public License along #
|
22
|
+
# with ruby-xquery. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
module LibXML::XML::XQuery::Namespaces
|
28
|
+
|
29
|
+
def namespaces
|
30
|
+
@namespaces ||= self.class::DEFAULT_NAMESPACES
|
31
|
+
end
|
32
|
+
|
33
|
+
def namespaces=(ns)
|
34
|
+
if url
|
35
|
+
@namespaces = self.class.namespaces[url] = ns
|
36
|
+
else
|
37
|
+
raise "can't set namespaces (document has no URL)"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.included(base)
|
42
|
+
base.const_set(:DEFAULT_NAMESPACES, [])
|
43
|
+
|
44
|
+
# container for XML::Node's access to its document's namespaces
|
45
|
+
base.instance_variable_set(
|
46
|
+
:@namespaces, Hash.new(base.const_get(:DEFAULT_NAMESPACES))
|
47
|
+
)
|
48
|
+
|
49
|
+
class << base; attr_reader :namespaces; end
|
50
|
+
|
51
|
+
# overwrite original methods
|
52
|
+
instance_methods.each { |method|
|
53
|
+
base.send(:define_method, method, instance_method(method))
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
[LibXML::XML::Document].each { |klass|
|
60
|
+
klass.send :include, LibXML::XML::XQuery::Namespaces
|
61
|
+
}
|
62
|
+
|
63
|
+
class LibXML::XML::Node
|
64
|
+
def namespaces
|
65
|
+
LibXML::XML::Document.namespaces[doc.url]
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-xquery, mimicking XQuery in Ruby. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
10
|
+
# #
|
11
|
+
# ruby-xquery is free software; you can redistribute it and/or modify it #
|
12
|
+
# under the terms of the GNU General Public License as published by the Free #
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
14
|
+
# any later version. #
|
15
|
+
# #
|
16
|
+
# ruby-xquery is distributed in the hope that it will be useful, but WITHOUT #
|
17
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
19
|
+
# more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU General Public License along #
|
22
|
+
# with ruby-xquery. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
class LibXML::XML::Attr
|
28
|
+
|
29
|
+
def to_s(sep = nil)
|
30
|
+
value.strip
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class LibXML::XML::Node
|
36
|
+
|
37
|
+
def to_s(sep = nil)
|
38
|
+
content.strip
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
class LibXML::XML::XPath::Object
|
44
|
+
|
45
|
+
def to_s(sep = ' | ')
|
46
|
+
map { |n| (c = n.to_s(sep)).empty? ? nil : c }.compact.join(sep)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-xquery, mimicking XQuery in Ruby. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
10
|
+
# #
|
11
|
+
# ruby-xquery is free software; you can redistribute it and/or modify it #
|
12
|
+
# under the terms of the GNU General Public License as published by the Free #
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
14
|
+
# any later version. #
|
15
|
+
# #
|
16
|
+
# ruby-xquery is distributed in the hope that it will be useful, but WITHOUT #
|
17
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
19
|
+
# more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU General Public License along #
|
22
|
+
# with ruby-xquery. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
require 'forwardable'
|
28
|
+
|
29
|
+
module LibXML::XML::XQuery::Uniqueness
|
30
|
+
|
31
|
+
extend Forwardable
|
32
|
+
|
33
|
+
DELEGATORS = %w[to_a each length size]
|
34
|
+
|
35
|
+
def_delegators *DELEGATORS
|
36
|
+
|
37
|
+
def to_a
|
38
|
+
if @_uniq
|
39
|
+
# return unique nodes according to their #to_s
|
40
|
+
seen = Hash.new { |h, k| h[k] = true; false }
|
41
|
+
uniq = []
|
42
|
+
|
43
|
+
_xquery_original_to_a.each { |n|
|
44
|
+
uniq << n unless seen[n.to_s]
|
45
|
+
}
|
46
|
+
|
47
|
+
uniq
|
48
|
+
else
|
49
|
+
_xquery_original_to_a
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def uniq
|
54
|
+
proxy = self.class.new.uniq!
|
55
|
+
proxy.instance_variable_set(:@_this, self)
|
56
|
+
|
57
|
+
class << proxy
|
58
|
+
(instance_methods - DELEGATORS).each { |method|
|
59
|
+
undef_method(method) unless method =~ /\A__/
|
60
|
+
}
|
61
|
+
|
62
|
+
def method_missing(*args)
|
63
|
+
block_given? ? @_this.send(*args) { |a| yield a } : @_this.send(*args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
proxy
|
68
|
+
end
|
69
|
+
|
70
|
+
def uniq!
|
71
|
+
@_uniq = true
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
def uniq?
|
76
|
+
@_uniq
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.included(base)
|
80
|
+
base.send(:alias_method, :_xquery_original_to_a, :to_a)
|
81
|
+
|
82
|
+
# overwrite original methods
|
83
|
+
instance_methods.each { |method|
|
84
|
+
base.send(:define_method, method, instance_method(method))
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
[LibXML::XML::XPath::Object].each { |klass|
|
91
|
+
klass.send :include, LibXML::XML::XQuery::Uniqueness
|
92
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module LibXML
|
2
|
+
|
3
|
+
module XML
|
4
|
+
|
5
|
+
module XQuery
|
6
|
+
|
7
|
+
module Version
|
8
|
+
|
9
|
+
MAJOR = 0
|
10
|
+
MINOR = 2
|
11
|
+
TINY = 2
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
# Returns array representation.
|
16
|
+
def to_a
|
17
|
+
[MAJOR, MINOR, TINY]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Short-cut for version string.
|
21
|
+
def to_s
|
22
|
+
to_a.join('.')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
VERSION = Version.to_s
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# ruby-xquery -- Libxml's XPath support + plain ol' Ruby = XQuery (kind of... #
|
5
|
+
# ;-) #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2008 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-xquery is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-xquery is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-xquery. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rubygems'
|
30
|
+
rescue LoadError
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'libxml'
|
34
|
+
|
35
|
+
raise "need libxml-ruby version >= 0.9.3, got #{LibXML::XML::VERSION}" \
|
36
|
+
unless LibXML::XML::VERSION >= '0.9.3'
|
37
|
+
|
38
|
+
# Libxml's XPath support + plain ol' Ruby = XQuery (kind of... ;-)
|
39
|
+
|
40
|
+
module LibXML::XML::XQuery
|
41
|
+
end
|
42
|
+
|
43
|
+
Dir[File.join(File.dirname(__FILE__), 'xquery', '**', '*.rb')].each { |rb|
|
44
|
+
require rb
|
45
|
+
}
|
data/lib/xml/xquery.rb
ADDED
data/spec/spec_helper.rb
ADDED
data/spec/xquery_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe LibXML::XML::XQuery do
|
4
|
+
|
5
|
+
it 'should find all acts' do
|
6
|
+
DOC['//ACT'].size.should == 5
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should find all acts with Hpricot-style syntax' do
|
10
|
+
(DOC/'//ACT').size.should == 5
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should find all speakers per act' do
|
14
|
+
DOC['//ACT'].map { |act|
|
15
|
+
act['descendant::node()/SPEAKER'].size
|
16
|
+
}.should == [259, 202, 252, 180, 257]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should find all unique speakers per act' do
|
20
|
+
DOC['//ACT'].map { |act|
|
21
|
+
act['descendant::node()/SPEAKER'].uniq.size
|
22
|
+
}.should == [14, 10, 15, 15, 13]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should find descendant::node() with abbreviated syntax' do
|
26
|
+
act = DOC['//ACT'].first
|
27
|
+
|
28
|
+
act['**/SPEAKER'].to_a.should == act['descendant::node()/SPEAKER'].to_a
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should not have any side-effects when using non-bang uniq' do
|
32
|
+
speakers = DOC['//ACT'].first['descendant::node()/SPEAKER']
|
33
|
+
|
34
|
+
lambda {
|
35
|
+
speakers.uniq
|
36
|
+
}.should_not change(speakers, :size)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should indeed have side-effects when using bang uniq' do
|
40
|
+
speakers = DOC['//ACT'].first['descendant::node()/SPEAKER']
|
41
|
+
|
42
|
+
lambda {
|
43
|
+
speakers.uniq!
|
44
|
+
}.should change(speakers, :size)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|