oai 0.0.2 → 0.0.3
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/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'
|