oai 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/oai/client.rb +79 -23
- data/lib/oai/get_record.rb +5 -1
- data/lib/oai/header.rb +6 -0
- data/lib/oai/identify.rb +2 -0
- data/lib/oai/record.rb +9 -0
- data/lib/oai/response.rb +10 -4
- data/lib/oai/xpath.rb +48 -5
- data/lib/test.rb +25 -0
- data/test/tc_exception.rb +19 -2
- data/test/tc_get_record.rb +6 -0
- data/test/tc_identify.rb +1 -1
- data/test/tc_libxml.rb +51 -0
- data/test/tc_list_identifiers.rb +0 -2
- data/test/tc_xpath.rb +29 -0
- data/test/test.xml +22 -0
- metadata +45 -35
- data/test.rb +0 -13
data/lib/oai/client.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'net/http'
|
3
|
-
require 'rexml/document'
|
4
3
|
require 'cgi'
|
5
4
|
require 'date'
|
6
5
|
|
@@ -10,8 +9,10 @@ module OAI
|
|
10
9
|
# a OAI-PMH server. The 6 OAI-PMH verbs translate directly to methods you
|
11
10
|
# can call on a OAI::Client object. Verb arguments are passed as a hash:
|
12
11
|
#
|
13
|
-
# client = OAI::Client.new '
|
14
|
-
# client.
|
12
|
+
# client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi'
|
13
|
+
# record = client.get_record :identifier => 'oai:pubmedcentral.gov:13901'
|
14
|
+
# for identifier in client.list_identifiers :metadata_prefix => 'oai_dc'
|
15
|
+
# puts identifier.
|
15
16
|
#
|
16
17
|
# It is worth noting that the api uses methods and parameter names with
|
17
18
|
# underscores in them rather than studly caps. So above list_identifiers
|
@@ -37,15 +38,40 @@ module OAI
|
|
37
38
|
# If you want to see debugging messages on STDERR use:
|
38
39
|
#
|
39
40
|
# client = OAI::Harvester.new 'http://example.com', :debug => true
|
41
|
+
#
|
42
|
+
# By default OAI verbs called on the client will return REXML::Element
|
43
|
+
# objects for metadata records, however if you wish you can use the
|
44
|
+
# :parser option to indicate you want to use 'libxml' instead, and get
|
45
|
+
# back XML::Node objects
|
46
|
+
#
|
47
|
+
# client = OAI::Harvester.new 'http://example.com', :parser => 'libxml'
|
40
48
|
|
41
49
|
def initialize(base_url, options={})
|
42
50
|
@base = URI.parse base_url
|
43
|
-
@debug = options
|
51
|
+
@debug = options.fetch(:debug, false)
|
52
|
+
@parser = options.fetch(:parser, 'rexml')
|
53
|
+
|
54
|
+
# load appropriate parser
|
55
|
+
case @parser
|
56
|
+
when 'libxml'
|
57
|
+
begin
|
58
|
+
require 'rubygems'
|
59
|
+
require 'xml/libxml'
|
60
|
+
rescue
|
61
|
+
raise OAI::Exception.new("xml/libxml not available")
|
62
|
+
end
|
63
|
+
when 'rexml'
|
64
|
+
require 'rexml/document'
|
65
|
+
require 'rexml/xpath'
|
66
|
+
else
|
67
|
+
raise OAI::Exception.new("unknown parser: #{@parser}")
|
68
|
+
end
|
44
69
|
end
|
45
70
|
|
46
71
|
# Equivalent to a Identify request. You'll get back a OAI::IdentifyResponse
|
47
72
|
# object which is essentially just a wrapper around a REXML::Document
|
48
|
-
# for the response.
|
73
|
+
# for the response. If you are created your client using the libxml
|
74
|
+
# parser then you will get an XML::Node object instead.
|
49
75
|
|
50
76
|
def identify
|
51
77
|
return IdentifyResponse.new(do_request(:verb => 'Identify'))
|
@@ -55,8 +81,7 @@ module OAI
|
|
55
81
|
# object is returned to you.
|
56
82
|
|
57
83
|
def list_metadata_formats(opts={})
|
58
|
-
opts[:verb]
|
59
|
-
verify_verb_arguments opts, [:verb, :identifier]
|
84
|
+
sanitize_verb_arguments 'ListMetadataFormats', opts, [:verb, :identifier]
|
60
85
|
return ListMetadataFormatsResponse.new(do_request(opts))
|
61
86
|
end
|
62
87
|
|
@@ -65,9 +90,9 @@ module OAI
|
|
65
90
|
# supported by the server.
|
66
91
|
|
67
92
|
def list_identifiers(opts={})
|
68
|
-
|
93
|
+
sanitize_verb_arguments 'ListIdentifiers', opts,
|
94
|
+
[:verb, :from, :until, :metadata_prefix, :set, :resumption_token]
|
69
95
|
add_default_metadata_prefix opts
|
70
|
-
verify_verb_arguments opts, [:verb, :from, :until, :metadata_prefix, :set, :resumption_token]
|
71
96
|
return ListIdentifiersResponse.new(do_request(opts))
|
72
97
|
end
|
73
98
|
|
@@ -76,9 +101,9 @@ module OAI
|
|
76
101
|
# which you can extract a OAI::Record object from.
|
77
102
|
|
78
103
|
def get_record(opts={})
|
79
|
-
|
104
|
+
sanitize_verb_arguments 'GetRecord', opts,
|
105
|
+
[:verb, :identifier, :metadata_prefix]
|
80
106
|
add_default_metadata_prefix opts
|
81
|
-
verify_verb_arguments opts, [:verb, :identifier, :metadata_prefix]
|
82
107
|
return GetRecordResponse.new(do_request(opts))
|
83
108
|
end
|
84
109
|
|
@@ -90,10 +115,9 @@ module OAI
|
|
90
115
|
# end
|
91
116
|
|
92
117
|
def list_records(opts={})
|
93
|
-
opts[:verb
|
94
|
-
add_default_metadata_prefix opts
|
95
|
-
verify_verb_arguments opts, [:verb, :from, :until, :set,
|
118
|
+
sanitize_verb_arguments 'ListRecords', opts, [:verb, :from, :until, :set,
|
96
119
|
:resumption_token, :metadata_prefix]
|
120
|
+
add_default_metadata_prefix opts
|
97
121
|
return ListRecordsResponse.new(do_request(opts))
|
98
122
|
end
|
99
123
|
|
@@ -106,8 +130,7 @@ module OAI
|
|
106
130
|
# end
|
107
131
|
|
108
132
|
def list_sets(opts={})
|
109
|
-
opts[:verb]
|
110
|
-
verify_verb_arguments opts, [:verb, :resumptionToken]
|
133
|
+
sanitize_verb_arguments 'ListSets', opts, [:verb, :resumptionToken]
|
111
134
|
return ListSetsResponse.new(do_request(opts))
|
112
135
|
end
|
113
136
|
|
@@ -131,18 +154,41 @@ module OAI
|
|
131
154
|
uri.query = parts.join('&')
|
132
155
|
debug("doing request: #{uri.to_s}")
|
133
156
|
|
134
|
-
# fire off the request and return
|
157
|
+
# fire off the request and return appropriate DOM object
|
135
158
|
begin
|
136
159
|
xml = Net::HTTP.get(uri)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
160
|
+
if @parser == 'libxml'
|
161
|
+
# remove default namespace for oai-pmh since libxml
|
162
|
+
# isn't able to use our xpaths to get at them
|
163
|
+
# if you know a way around thins please let me know
|
164
|
+
xml = xml.gsub(
|
165
|
+
/xmlns=\"http:\/\/www.openarchives.org\/OAI\/.\..\/\"/, '')
|
166
|
+
end
|
167
|
+
return load_document(xml)
|
168
|
+
rescue StandardError => e
|
142
169
|
raise OAI::Exception, 'HTTP level error during OAI request: '+e, caller
|
143
170
|
end
|
144
171
|
end
|
145
172
|
|
173
|
+
def load_document(xml)
|
174
|
+
case @parser
|
175
|
+
when 'libxml'
|
176
|
+
begin
|
177
|
+
parser = XML::Parser.new()
|
178
|
+
parser.string = xml
|
179
|
+
return parser.parse
|
180
|
+
rescue XML::Parser::ParseError => e
|
181
|
+
raise OAI::Exception, 'response not well formed XML: '+e, caller
|
182
|
+
end
|
183
|
+
when 'rexml'
|
184
|
+
begin
|
185
|
+
return REXML::Document.new(xml)
|
186
|
+
rescue REXML::ParseException => e
|
187
|
+
raise OAI::Exception, 'response not well formed XML: '+e, caller
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
146
192
|
# convert foo_bar to fooBar thus allowing our ruby code to use
|
147
193
|
# the typical underscore idiom
|
148
194
|
def studly(s)
|
@@ -160,7 +206,17 @@ module OAI
|
|
160
206
|
end
|
161
207
|
end
|
162
208
|
|
163
|
-
def
|
209
|
+
def sanitize_verb_arguments(verb, opts, valid_opts)
|
210
|
+
# opts could mistakenly not be a hash if the method was called wrong
|
211
|
+
# client.get_record(12) instead of client.get_record(:identifier => 12)
|
212
|
+
unless opts.kind_of?(Hash)
|
213
|
+
raise OAI::Exception.new("method options must be passed as a hash")
|
214
|
+
end
|
215
|
+
|
216
|
+
# add the verb
|
217
|
+
opts[:verb] = verb
|
218
|
+
|
219
|
+
# make sure options aren't using studly caps, and that they're legit
|
164
220
|
opts.keys.each do |opt|
|
165
221
|
if opt =~ /[A-Z]/
|
166
222
|
raise OAI::Exception.new("#{opt} should use underscores")
|
data/lib/oai/get_record.rb
CHANGED
data/lib/oai/header.rb
CHANGED
@@ -4,9 +4,15 @@ module OAI
|
|
4
4
|
attr_accessor :identifier, :datestamp, :set_spec
|
5
5
|
|
6
6
|
def initialize(element)
|
7
|
+
@status = get_attribute(element, 'status')
|
7
8
|
@identifier = xpath(element, './/identifier')
|
8
9
|
@datestamp = xpath(element, './/datestamp')
|
9
10
|
@set_spec = xpath(element, './/setSpec')
|
10
11
|
end
|
12
|
+
|
13
|
+
def deleted?
|
14
|
+
return true unless @status == 'deleted'
|
15
|
+
end
|
16
|
+
|
11
17
|
end
|
12
18
|
end
|
data/lib/oai/identify.rb
CHANGED
@@ -21,6 +21,8 @@ module OAI
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# returns REXML::Element nodes for each description section
|
24
|
+
# if the OAI::Client was configured to use libxml then you will
|
25
|
+
# instead get a XML::Node object.
|
24
26
|
def descriptions
|
25
27
|
return xpath_all(doc, './/Identify/description')
|
26
28
|
end
|
data/lib/oai/record.rb
CHANGED
@@ -4,6 +4,9 @@ module OAI
|
|
4
4
|
# or ListRecords request. Each record will have a header and metadata
|
5
5
|
# attribute. The header is a OAI::Header object and the metadata is
|
6
6
|
# a REXML::Element object for that chunk of XML.
|
7
|
+
#
|
8
|
+
# Note: if your OAI::Client was configured to use the 'libxml' parser
|
9
|
+
# metadata will return a XML::Node object instead.
|
7
10
|
|
8
11
|
class Record
|
9
12
|
include OAI::XPath
|
@@ -13,5 +16,11 @@ module OAI
|
|
13
16
|
@header = OAI::Header.new xpath_first(element, './/header')
|
14
17
|
@metadata = xpath_first(element, './/metadata')
|
15
18
|
end
|
19
|
+
|
20
|
+
# a convenience method which digs into the header status attribute
|
21
|
+
# and returns true if the value is set to 'deleted'
|
22
|
+
def deleted?
|
23
|
+
return @header.deleted?
|
24
|
+
end
|
16
25
|
end
|
17
26
|
end
|
data/lib/oai/response.rb
CHANGED
@@ -9,11 +9,17 @@ module OAI
|
|
9
9
|
|
10
10
|
# throw an exception if there was an error
|
11
11
|
error = xpath_first(doc, './/error')
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
return unless error
|
13
|
+
|
14
|
+
case error.class.to_s
|
15
|
+
when 'REXML::Element'
|
16
|
+
message = error.text
|
17
|
+
code = error.attributes['code']
|
18
|
+
when 'XML::Node'
|
19
|
+
message = error.content
|
20
|
+
code = error.property('code')
|
16
21
|
end
|
22
|
+
raise OAI::Exception.new("#{message} [#{code}]")
|
17
23
|
end
|
18
24
|
|
19
25
|
end
|
data/lib/oai/xpath.rb
CHANGED
@@ -1,21 +1,64 @@
|
|
1
|
-
require 'rexml/xpath'
|
2
|
-
|
3
1
|
module OAI
|
4
2
|
module XPath
|
3
|
+
|
4
|
+
# get all matching nodes
|
5
5
|
def xpath_all(doc, path)
|
6
|
-
|
6
|
+
case parser_type(doc)
|
7
|
+
when 'libxml'
|
8
|
+
return doc.find(path)
|
9
|
+
when 'rexml'
|
10
|
+
return REXML::XPath.match(doc, path)
|
11
|
+
end
|
12
|
+
return []
|
7
13
|
end
|
8
14
|
|
15
|
+
# get first matching node
|
9
16
|
def xpath_first(doc, path)
|
10
17
|
elements = xpath_all(doc, path)
|
11
18
|
return elements[0] if elements != nil
|
12
19
|
return nil
|
13
20
|
end
|
14
21
|
|
22
|
+
# get text for first matching node
|
15
23
|
def xpath(doc, path)
|
16
|
-
|
17
|
-
return
|
24
|
+
el = xpath_first(doc, path)
|
25
|
+
return unless el
|
26
|
+
case parser_type(doc)
|
27
|
+
when 'libxml'
|
28
|
+
return el.content
|
29
|
+
when 'rexml'
|
30
|
+
return el.text
|
31
|
+
end
|
18
32
|
return nil
|
19
33
|
end
|
34
|
+
|
35
|
+
# figure out an attribute
|
36
|
+
def get_attribute(node, attr_name)
|
37
|
+
case node.class.to_s
|
38
|
+
when 'REXML::Element'
|
39
|
+
return node.attribute(attr_name)
|
40
|
+
when 'XML::Node'
|
41
|
+
return node.property(attr_name)
|
42
|
+
end
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# figure out what sort of object we should do xpath on
|
49
|
+
def parser_type(x)
|
50
|
+
case x.class.to_s
|
51
|
+
when 'XML::Document'
|
52
|
+
return 'libxml'
|
53
|
+
when 'XML::Node'
|
54
|
+
return 'libxml'
|
55
|
+
when 'XML::Node::Set'
|
56
|
+
return 'libxml'
|
57
|
+
when 'REXML::Element'
|
58
|
+
return 'rexml'
|
59
|
+
when 'REXML::Document'
|
60
|
+
return 'rexml'
|
61
|
+
end
|
62
|
+
end
|
20
63
|
end
|
21
64
|
end
|
data/lib/test.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'oai'
|
2
|
+
|
3
|
+
buffer = ""
|
4
|
+
start_time = Time.now()
|
5
|
+
|
6
|
+
client = OAI::Client.new 'http://digitalcollections.library.oregonstate.edu/cgi-bin/oai.exe', :parser =>'libxml'
|
7
|
+
|
8
|
+
last_check = Date.new(2006,9,5)
|
9
|
+
records = client.list_records
|
10
|
+
# :set => 'archives', :metadata_prefix => 'oai_dc', :from => last_check
|
11
|
+
|
12
|
+
x = 0
|
13
|
+
records.each do |record|
|
14
|
+
#fields = record.serialize_metadata(record.metadata, "oai_dc", "Oai_Dc")
|
15
|
+
#puts "Primary Title: " + fields.title[0] + "\n"
|
16
|
+
puts "Identifier: " + record.header.identifier + "\n"
|
17
|
+
x += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
end_time = Time.now()
|
21
|
+
|
22
|
+
puts buffer
|
23
|
+
puts "Time to run: " + (end_time - start_time).to_s + "\n"
|
24
|
+
puts "Records returned: " + x.to_s
|
25
|
+
|
data/test/tc_exception.rb
CHANGED
@@ -6,16 +6,33 @@ class ExceptionTest < Test::Unit::TestCase
|
|
6
6
|
client.identify
|
7
7
|
flunk 'did not throw expected exception'
|
8
8
|
rescue OAI::Exception => e
|
9
|
-
assert_match
|
9
|
+
assert_match /^HTTP level error/, e.to_s, 'include error message'
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_xml_error
|
14
|
-
client = OAI::Client.new 'http://www.
|
14
|
+
client = OAI::Client.new 'http://www.yahoo.com'
|
15
15
|
begin
|
16
16
|
client.identify
|
17
17
|
rescue OAI::Exception => e
|
18
18
|
assert_match /response not well formed XML/, e.to_s, 'xml error'
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
def test_oai_error
|
23
|
+
client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi'
|
24
|
+
assert_raises(OAI::Exception) do
|
25
|
+
client.list_identifiers :resumption_token => 'bogus'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# must pass in options as a hash
|
30
|
+
def test_parameter_error
|
31
|
+
client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi'
|
32
|
+
assert_raises(OAI::Exception) {client.get_record('foo')}
|
33
|
+
assert_raises(OAI::Exception) {client.list_identifiers('foo')}
|
34
|
+
assert_raises(OAI::Exception) {client.list_records('foo')}
|
35
|
+
assert_raises(OAI::Exception) {client.list_metadata_formats('foo')}
|
36
|
+
assert_raises(OAI::Exception) {client.list_sets('foo')}
|
37
|
+
end
|
21
38
|
end
|
data/test/tc_get_record.rb
CHANGED
@@ -24,4 +24,10 @@ class GetRecordTest < Test::Unit::TestCase
|
|
24
24
|
assert_match /The request includes illegal arguments/, e.to_s
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
def test_deleted_record
|
29
|
+
client = OAI::Client.new 'http://ir.library.oregonstate.edu/dspace-oai/request'
|
30
|
+
record = client.get_record :identifier => 'oai:ir.library.oregonstate.edu:1957/19'
|
31
|
+
assert record.deleted?
|
32
|
+
end
|
27
33
|
end
|
data/test/tc_identify.rb
CHANGED
@@ -3,6 +3,6 @@ class IdentifyTest < Test::Unit::TestCase
|
|
3
3
|
client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi'
|
4
4
|
response = client.identify
|
5
5
|
assert_kind_of OAI::IdentifyResponse, response
|
6
|
-
assert_equal 'PubMed Central (PMC3 - NLM DTD) [http://www.pubmedcentral.
|
6
|
+
assert_equal 'PubMed Central (PMC3 - NLM DTD) [http://www.pubmedcentral.gov/oai/oai.cgi]', response.to_s
|
7
7
|
end
|
8
8
|
end
|
data/test/tc_libxml.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
class LibXMLTest < Test::Unit::TestCase
|
2
|
+
|
3
|
+
def test_oai_exception
|
4
|
+
return unless have_libxml
|
5
|
+
|
6
|
+
uri = 'http://www.pubmedcentral.gov/oai/oai.cgi'
|
7
|
+
client = OAI::Client.new uri, :parser => 'libxml'
|
8
|
+
assert_raises(OAI::Exception) {client.get_record(:identifier => 'nosuchid')}
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_list_records
|
12
|
+
return unless have_libxml
|
13
|
+
|
14
|
+
# since there is regex magic going on to remove default oai namespaces
|
15
|
+
# it's worth trying a few different oai targets
|
16
|
+
oai_targets = %w{
|
17
|
+
http://etd.caltech.edu:80/ETD-db/OAI/oai
|
18
|
+
http://ir.library.oregonstate.edu/dspace-oai/request
|
19
|
+
http://libeprints.open.ac.uk/perl/oai2
|
20
|
+
http://memory.loc.gov/cgi-bin/oai2_0
|
21
|
+
}
|
22
|
+
|
23
|
+
oai_targets.each do |uri|
|
24
|
+
client = OAI::Client.new uri, :parser => 'libxml'
|
25
|
+
records = client.list_records
|
26
|
+
records.each do |record|
|
27
|
+
assert record.header.identifier
|
28
|
+
next unless record.deleted?
|
29
|
+
assert_kind_of XML::Node, record.metadata
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_deleted_record
|
35
|
+
uri = 'http://ir.library.oregonstate.edu/dspace-oai/request'
|
36
|
+
client = OAI::Client.new(uri, :parser => 'libxml')
|
37
|
+
record = client.get_record :identifier => 'oai:ir.library.oregonstate.edu:1957/19'
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def have_libxml
|
43
|
+
begin
|
44
|
+
require 'xml/libxml'
|
45
|
+
return true
|
46
|
+
rescue
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/test/tc_list_identifiers.rb
CHANGED
data/test/tc_xpath.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'oai/xpath'
|
2
|
+
|
3
|
+
class XpathTest < Test::Unit::TestCase
|
4
|
+
include OAI::XPath
|
5
|
+
|
6
|
+
def test_rexml
|
7
|
+
require 'rexml/document'
|
8
|
+
doc = REXML::Document.new(File.new('test/test.xml'))
|
9
|
+
assert_equal xpath(doc, './/responseDate'), '2006-09-11T14:33:15Z'
|
10
|
+
assert_equal xpath(doc, './/foobar'), nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_libxml
|
14
|
+
begin
|
15
|
+
require 'xml/libxml'
|
16
|
+
rescue
|
17
|
+
# libxml not available so nothing to test!
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
doc = XML::Document.file('test/test.xml')
|
22
|
+
assert_equal xpath(doc, './/responseDate'), '2006-09-11T14:33:15Z'
|
23
|
+
assert_equal xpath(doc, './/foobar'), nil
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
__END__
|
29
|
+
|
data/test/test.xml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<OAI-PMH xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
|
3
|
+
<responseDate>2006-09-11T14:33:15Z</responseDate>
|
4
|
+
<request verb="Identify">http://www.pubmedcentral.gov/oai/oai.cgi</request>
|
5
|
+
<Identify>
|
6
|
+
<repositoryName>PubMed Central (PMC3 - NLM DTD)</repositoryName>
|
7
|
+
<baseURL>http://www.pubmedcentral.gov/oai/oai.cgi</baseURL>
|
8
|
+
<protocolVersion>2.0</protocolVersion>
|
9
|
+
<adminEmail>oai@ncbi.nlm.nih.gov</adminEmail>
|
10
|
+
<earliestDatestamp>1999-01-01</earliestDatestamp>
|
11
|
+
<deletedRecord>no</deletedRecord>
|
12
|
+
<granularity>YYYY-MM-DD</granularity>
|
13
|
+
<description>
|
14
|
+
<oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
|
15
|
+
<scheme>oai</scheme>
|
16
|
+
<repositoryIdentifier>pubmedcentral.gov</repositoryIdentifier>
|
17
|
+
<delimiter>:</delimiter>
|
18
|
+
<sampleIdentifier>oai:pubmedcentral.gov:13900</sampleIdentifier>
|
19
|
+
</oai-identifier>
|
20
|
+
</description>
|
21
|
+
</Identify>
|
22
|
+
</OAI-PMH>
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.0
|
3
3
|
specification_version: 1
|
4
4
|
name: oai
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.0.3
|
7
|
+
date: 2006-09-19 00:00:00 -04:00
|
8
8
|
summary: A ruby library for working with the Open Archive Initiative Protocol for Metadata Harvesting (OAI-PMH)
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: ehs@pobox.com
|
12
12
|
homepage: http://www.textualize.com/ruby-marc
|
13
13
|
rubyforge_project:
|
@@ -18,45 +18,55 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
28
|
+
post_install_message:
|
29
29
|
authors:
|
30
|
-
|
30
|
+
- Ed Summers
|
31
31
|
files:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
32
|
+
- lib/oai
|
33
|
+
- lib/oai.rb
|
34
|
+
- lib/test.rb
|
35
|
+
- lib/oai/client.rb
|
36
|
+
- lib/oai/exception.rb
|
37
|
+
- lib/oai/get_record.rb
|
38
|
+
- lib/oai/header.rb
|
39
|
+
- lib/oai/identify.rb
|
40
|
+
- lib/oai/list_identifiers.rb
|
41
|
+
- lib/oai/list_metadata_formats.rb
|
42
|
+
- lib/oai/list_records.rb
|
43
|
+
- lib/oai/list_sets.rb
|
44
|
+
- lib/oai/metadata_format.rb
|
45
|
+
- lib/oai/record.rb
|
46
|
+
- lib/oai/response.rb
|
47
|
+
- lib/oai/set.rb
|
48
|
+
- lib/oai/xpath.rb
|
49
|
+
- test/tc_exception.rb
|
50
|
+
- test/tc_get_record.rb
|
51
|
+
- test/tc_identify.rb
|
52
|
+
- test/tc_libxml.rb
|
53
|
+
- test/tc_list_identifiers.rb
|
54
|
+
- test/tc_list_metadata_formats.rb
|
55
|
+
- test/tc_list_records.rb
|
56
|
+
- test/tc_list_sets.rb
|
57
|
+
- test/tc_xpath.rb
|
58
|
+
- test/test.xml
|
59
|
+
test_files: []
|
60
|
+
|
57
61
|
rdoc_options: []
|
62
|
+
|
58
63
|
extra_rdoc_files: []
|
64
|
+
|
59
65
|
executables: []
|
66
|
+
|
60
67
|
extensions: []
|
68
|
+
|
61
69
|
requirements: []
|
62
|
-
|
70
|
+
|
71
|
+
dependencies: []
|
72
|
+
|
data/test.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift 'lib'
|
4
|
-
|
5
|
-
require 'test/unit'
|
6
|
-
require 'oai'
|
7
|
-
require 'test/tc_list_identifiers'
|
8
|
-
require 'test/tc_list_metadata_formats'
|
9
|
-
require 'test/tc_identify'
|
10
|
-
require 'test/tc_get_record'
|
11
|
-
require 'test/tc_list_records'
|
12
|
-
require 'test/tc_list_sets'
|
13
|
-
require 'test/tc_exception'
|