dor-services 2.2.4
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/datastreams/content_metadata_ds.rb +12 -0
- data/lib/datastreams/embargo_metadata_ds.rb +107 -0
- data/lib/datastreams/events_ds.rb +58 -0
- data/lib/datastreams/identity_metadata_ds.rb +28 -0
- data/lib/datastreams/ng_tidy.rb +19 -0
- data/lib/datastreams/simple_dublin_core_ds.rb +23 -0
- data/lib/datastreams/workflow_definition_ds.rb +105 -0
- data/lib/datastreams/workflow_ds.rb +16 -0
- data/lib/dor-services.rb +19 -0
- data/lib/dor/admin_policy_object.rb +11 -0
- data/lib/dor/base.rb +81 -0
- data/lib/dor/cleanup_service.rb +32 -0
- data/lib/dor/config.rb +45 -0
- data/lib/dor/digital_stacks_service.rb +82 -0
- data/lib/dor/druid_utils.rb +41 -0
- data/lib/dor/embargo.rb +41 -0
- data/lib/dor/exceptions.rb +13 -0
- data/lib/dor/item.rb +141 -0
- data/lib/dor/metadata_handlers/catalog_handler.rb +22 -0
- data/lib/dor/metadata_handlers/mdtoolkit_handler.rb +42 -0
- data/lib/dor/metadata_service.rb +88 -0
- data/lib/dor/mods2dc.xslt +447 -0
- data/lib/dor/provenance_metadata_service.rb +65 -0
- data/lib/dor/registration_service.rb +87 -0
- data/lib/dor/rsolr.rb +27 -0
- data/lib/dor/sdr_ingest_service.rb +117 -0
- data/lib/dor/search_service.rb +86 -0
- data/lib/dor/suri_service.rb +37 -0
- data/lib/dor/tei2dc.xslt +102 -0
- data/lib/dor/workflow_object.rb +13 -0
- data/lib/dor/workflow_service.rb +111 -0
- data/lib/gsearch/demoFoxmlToSolr.xslt +384 -0
- data/lib/gsearch/schema.xml +229 -0
- data/lib/tasks/rdoc.rake +32 -0
- data/lib/xml_models/foxml.rb +261 -0
- data/lib/xml_models/identity_metadata/dublin_core.rb +119 -0
- data/lib/xml_models/identity_metadata/identity_metadata.rb +288 -0
- metadata +462 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'date'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Dor
|
6
|
+
class ProvenanceMetadataService
|
7
|
+
|
8
|
+
def self.add_provenance(dor_item, workflow_id, event_text)
|
9
|
+
druid = dor_item.pid
|
10
|
+
# workflow_xml = get_workflow_xml(druid, workflow_id)
|
11
|
+
workflow_provenance = create_workflow_provenance(druid, workflow_id, event_text)
|
12
|
+
dsname = 'provenanceMetadata'
|
13
|
+
if dor_item.datastream_names.include?(dsname)
|
14
|
+
ds = dor_item.datastreams[dsname]
|
15
|
+
old_provenance = ds.content
|
16
|
+
ds.ng_xml = update_provenance(old_provenance, workflow_provenance)
|
17
|
+
else
|
18
|
+
ds = dor_item.datastreams[dsname]
|
19
|
+
ds.label = 'Provenance Metadata'
|
20
|
+
ds.ng_xml = workflow_provenance
|
21
|
+
end
|
22
|
+
ds.save
|
23
|
+
end
|
24
|
+
|
25
|
+
# not used
|
26
|
+
def self.get_workflow_xml(druid, workflow_id)
|
27
|
+
Dor::WorkflowService.get_workflow_xml('dor', druid, workflow_id)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
def self.create_workflow_provenance(druid, workflow_id, event_text)
|
32
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
33
|
+
xml.provenanceMetadata(:objectId => druid) {
|
34
|
+
xml.agent(:name => 'DOR') {
|
35
|
+
xml.what(:object => druid) {
|
36
|
+
xml.event(:who => "DOR-#{workflow_id}", :when => Time.new.iso8601) {
|
37
|
+
xml.text(event_text)
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
builder.doc
|
44
|
+
end
|
45
|
+
|
46
|
+
# Reformat the XML
|
47
|
+
# @param[String]
|
48
|
+
def self.parse_xml_remove_blank_nodes(old_provenance)
|
49
|
+
# http://blog.slashpoundbang.com/post/1454850669/how-to-pretty-print-xml-with-nokogiri
|
50
|
+
Nokogiri::XML(old_provenance) { |x| x.noblanks }
|
51
|
+
end
|
52
|
+
|
53
|
+
# Append new stanzas in the contentMetadata for the googleMETS and technicalMetadata files
|
54
|
+
# @param[String, Hash<Symbol,String>]
|
55
|
+
def self.update_provenance(old_provenance, workflow_provenance)
|
56
|
+
pm_xml = Nokogiri::XML(old_provenance)
|
57
|
+
builder = Nokogiri::XML::Builder.with(pm_xml.at 'provenanceMetadata') do |xml|
|
58
|
+
xml << workflow_provenance.xpath('/provenanceMetadata/agent').first.to_xml
|
59
|
+
end
|
60
|
+
parse_xml_remove_blank_nodes(builder.to_xml)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'active_fedora'
|
2
|
+
require 'uuidtools'
|
3
|
+
require 'xml_models/foxml'
|
4
|
+
require 'xml_models/identity_metadata/identity_metadata'
|
5
|
+
|
6
|
+
require 'dor/search_service'
|
7
|
+
|
8
|
+
module Dor
|
9
|
+
|
10
|
+
class RegistrationService
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def register_object(params = {})
|
14
|
+
[:object_type, :label].each do |required_param|
|
15
|
+
unless params[required_param]
|
16
|
+
raise Dor::ParameterError, "#{required_param.inspect} must be specified in call to #{self.name}.register_object"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
object_type = params[:object_type]
|
21
|
+
content_model = params[:content_model]
|
22
|
+
admin_policy = params[:admin_policy]
|
23
|
+
label = params[:label]
|
24
|
+
source_id = params[:source_id] || {}
|
25
|
+
other_ids = params[:other_ids] || {}
|
26
|
+
tags = params[:tags] || []
|
27
|
+
parent = params[:parent]
|
28
|
+
pid = nil
|
29
|
+
if params[:pid]
|
30
|
+
pid = params[:pid]
|
31
|
+
existing_pid = SearchService.query_by_id(pid).first
|
32
|
+
unless existing_pid.nil?
|
33
|
+
raise Dor::DuplicateIdError.new(existing_pid), "An object with the PID #{pid} has already been registered."
|
34
|
+
end
|
35
|
+
else
|
36
|
+
pid = Dor::SuriService.mint_id
|
37
|
+
end
|
38
|
+
|
39
|
+
if (other_ids.has_key?(:uuid) or other_ids.has_key?('uuid')) == false
|
40
|
+
other_ids[:uuid] = UUIDTools::UUID.timestamp_create.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
apo_object = Dor::AdminPolicyObject.load_instance(admin_policy)
|
44
|
+
adm_xml = apo_object.datastreams['administrativeMetadata'].ng_xml
|
45
|
+
agreement_id = adm_xml.at('/administrativeMetadata/registration/agreementId/text()').to_s
|
46
|
+
|
47
|
+
idmd = IdentityMetadata.new
|
48
|
+
|
49
|
+
unless source_id.empty?
|
50
|
+
source_name = source_id.keys.first
|
51
|
+
source_value = source_id[source_name]
|
52
|
+
existing_pid = SearchService.query_by_id("#{source_name}:#{source_value}").first
|
53
|
+
unless existing_pid.nil?
|
54
|
+
raise Dor::DuplicateIdError.new(existing_pid), "An object with the source ID '#{source_name}:#{source_value}' has already been registered."
|
55
|
+
end
|
56
|
+
idmd.sourceId.source = source_name
|
57
|
+
idmd.sourceId.value = source_value
|
58
|
+
end
|
59
|
+
|
60
|
+
idmd.objectId = pid
|
61
|
+
idmd.objectCreators << 'DOR'
|
62
|
+
idmd.objectLabels << label
|
63
|
+
idmd.objectTypes << object_type
|
64
|
+
idmd.adminPolicy = admin_policy
|
65
|
+
idmd.agreementId = agreement_id
|
66
|
+
other_ids.each_pair { |name,value| idmd.add_identifier(name,value) }
|
67
|
+
tags.each { |tag| idmd.add_tag(tag) }
|
68
|
+
|
69
|
+
foxml = Foxml.new(pid, label, content_model, idmd.to_xml, parent)
|
70
|
+
foxml.admin_policy_object = admin_policy
|
71
|
+
rdf = foxml.xml.at('//rdf:Description', { 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' })
|
72
|
+
rels = adm_xml.xpath('/administrativeMetadata/relationships/*')
|
73
|
+
rels.each { |rel| rdf.add_child(rel.clone) }
|
74
|
+
|
75
|
+
repo = ActiveFedora.fedora
|
76
|
+
http_response = repo.ingest(foxml.to_xml(:undent_datastreams => true))
|
77
|
+
result = {
|
78
|
+
:response => http_response,
|
79
|
+
:pid => pid
|
80
|
+
}
|
81
|
+
return(result)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
data/lib/dor/rsolr.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
|
5
|
+
class RSolrConnection
|
6
|
+
|
7
|
+
def execute client, request_context
|
8
|
+
$stderr.puts request_context.inspect
|
9
|
+
resource = RestClient::Resource.new(
|
10
|
+
request_context[:uri].to_s,
|
11
|
+
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(Dor::Config.fedora.cert_file)),
|
12
|
+
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read(Dor::Config.fedora.key_file), Dor::Config.fedora.key_pass)
|
13
|
+
)
|
14
|
+
result = {}
|
15
|
+
resource.send(request_context[:method]) { |response, request, result, &block|
|
16
|
+
result = {
|
17
|
+
:status => response.net_http_res.code.to_i,
|
18
|
+
:headers => response.net_http_res.to_hash,
|
19
|
+
:body => response.net_http_res.body
|
20
|
+
}
|
21
|
+
}
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'lyber-utils'
|
2
|
+
|
3
|
+
module Dor
|
4
|
+
class SdrIngestService
|
5
|
+
|
6
|
+
Config.declare(:sdr) do
|
7
|
+
local_workspace_root '/dor/workspace'
|
8
|
+
local_export_home '/dor/export'
|
9
|
+
datastreams do
|
10
|
+
contentMetadata 'required'
|
11
|
+
descMetadata 'required'
|
12
|
+
identityMetadata 'required'
|
13
|
+
provenanceMetadata 'required'
|
14
|
+
relationshipMetadata 'required'
|
15
|
+
technicalMetadata 'required'
|
16
|
+
rightsMetadata 'optional'
|
17
|
+
sourceMetadata 'optional'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Some boilerplace entries for the bagit metadata file
|
22
|
+
METADATA_INFO = {
|
23
|
+
'Source-Organization' => 'Stanford University Libraries',
|
24
|
+
'Stanford-Content-Metadata' => 'data/metadata/contentMetadata.xml',
|
25
|
+
'Stanford-Identity-Metadata' => 'data/metadata/identityMetadata.xml',
|
26
|
+
'Stanford-Provenance-Metadata' => 'data/metadata/provenanceMetadata.xml'
|
27
|
+
}
|
28
|
+
|
29
|
+
# Create a bagit object and fill it with content
|
30
|
+
# Then tar it
|
31
|
+
# @param [LyberCore::Robots::WorkItem]
|
32
|
+
def self.transfer(dor_item, agreement_id)
|
33
|
+
druid = dor_item.pid
|
34
|
+
content_dir = Druid.new(druid).path(Config.sdr.local_workspace_root)
|
35
|
+
|
36
|
+
# Create the bag
|
37
|
+
bag_dir = File.join(Config.sdr.local_export_home, druid)
|
38
|
+
export_bag = LyberUtils::BagitBag.new(bag_dir)
|
39
|
+
|
40
|
+
# Fill the bag
|
41
|
+
export_bag.add_content_files(content_dir, use_links=true)
|
42
|
+
add_metadata_datastreams(dor_item, export_bag)
|
43
|
+
export_bag.write_metadata_info(metadata_info(druid, agreement_id))
|
44
|
+
export_bag.write_manifests()
|
45
|
+
export_bag.validate()
|
46
|
+
|
47
|
+
unless LyberUtils::FileUtilities.tar_object(bag_dir)
|
48
|
+
raise 'Unable to tar the bag'
|
49
|
+
end
|
50
|
+
|
51
|
+
# Now bootstrap SDR workflow queue to start SDR robots
|
52
|
+
Dor::WorkflowService.create_workflow('sdr', druid, 'sdrIngestWF', read_sdr_workflow_xml(), {:create_ds => false})
|
53
|
+
end
|
54
|
+
|
55
|
+
# Read in the XML file needed to initialize the SDR workflow
|
56
|
+
# @return [String]
|
57
|
+
def self.read_sdr_workflow_xml()
|
58
|
+
return IO.read(File.join("#{ROBOT_ROOT}", "config", "workflows", "sdrIngestWF", "sdrIngestWF.xml"))
|
59
|
+
end
|
60
|
+
|
61
|
+
# For each of the metadata files or datastreams, create a file in in the bag's data/metadata folder
|
62
|
+
# @param[String, LyberUtils::BagitBag]
|
63
|
+
def self.add_metadata_datastreams(dor_item, export_bag)
|
64
|
+
Config.sdr.datastreams.to_hash.each_pair do |ds_name, required|
|
65
|
+
# ds_name in this context is a symbol, so convert it to a string
|
66
|
+
filename = "#{ds_name.to_s}.xml"
|
67
|
+
metadata_string = self.get_datastream_content(dor_item, ds_name.to_s, required)
|
68
|
+
self.export_metadata_string(metadata_string, filename, export_bag) unless metadata_string.nil?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# create a link to a metadata file in the bag's data/metadata folder
|
73
|
+
def self.export_metadata_file(metadata_dir, filename, bag)
|
74
|
+
metadata_file = File.join(metadata_dir, filename)
|
75
|
+
bag_metadata_dir = File.join(bag.bag_dir, 'data', 'metadata')
|
76
|
+
if (File.exist?(metadata_file))
|
77
|
+
bag_file = File.join(bag_metadata_dir, filename)
|
78
|
+
File.link(metadata_file, bag_file)
|
79
|
+
return true
|
80
|
+
else
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# return the content of the specied datastream if it exists
|
86
|
+
# if non-existant, return nil or raise exception depending on value of required
|
87
|
+
def self.get_datastream_content(dor_item, ds_name, required)
|
88
|
+
ds = (ds_name == 'relationshipMetadata' ? 'RELS-EXT' : ds_name)
|
89
|
+
if dor_item.datastreams_in_fedora.keys.include?(ds)
|
90
|
+
return dor_item.datastreams[ds].content
|
91
|
+
elsif (required == 'optional')
|
92
|
+
return nil
|
93
|
+
else
|
94
|
+
raise "required datastream #{ds_name} not found in DOR"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# create a file in the bag's data/metadata folder containing the metadata string
|
99
|
+
# @param[String, String, LyberUtils::BagitBag]
|
100
|
+
def self.export_metadata_string(metadata_string, filename, bag)
|
101
|
+
bag.add_metadata_file_from_string(metadata_string, filename)
|
102
|
+
end
|
103
|
+
|
104
|
+
# merge item-specific data into the standard hash of metadata information
|
105
|
+
# @param [String, String]
|
106
|
+
def self.metadata_info(druid, agreement_id)
|
107
|
+
item_info = {
|
108
|
+
'External-Identifier' => druid,
|
109
|
+
'Stanford-Agreement-ID' => agreement_id
|
110
|
+
}
|
111
|
+
merged_info = item_info.merge(METADATA_INFO)
|
112
|
+
return merged_info
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
module Dor
|
5
|
+
|
6
|
+
class SearchService
|
7
|
+
|
8
|
+
RISEARCH_TEMPLATE = "select $object from <#ri> where $object <dc:identifier> '%s'"
|
9
|
+
|
10
|
+
Config.declare(:gsearch) {
|
11
|
+
url nil
|
12
|
+
instance_eval do
|
13
|
+
def client
|
14
|
+
RestClient::Resource.new(
|
15
|
+
self.url,
|
16
|
+
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read(Config.fedora.cert_file)),
|
17
|
+
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read(Config.fedora.key_file), Config.fedora.key_pass)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
def reindex(*pids)
|
26
|
+
fedora_client = Config.fedora.client
|
27
|
+
solr_client = Config.gsearch.client
|
28
|
+
xsl = Nokogiri::XSLT(File.read(File.expand_path('../../gsearch/demoFoxmlToSolr.xslt', __FILE__)))
|
29
|
+
pids.in_groups_of(20, false) do |group|
|
30
|
+
doc = Nokogiri::XML('<update/>')
|
31
|
+
group.each do |pid|
|
32
|
+
begin
|
33
|
+
foxml = Dor::Base.get_foxml(pid,true)
|
34
|
+
doc.root.add_child(xsl.transform(foxml).root)
|
35
|
+
rescue RestClient::ResourceNotFound
|
36
|
+
doc.root.add_child("<delete><id>#{pid}</id></delete>")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
yield group if block_given?
|
40
|
+
solr_client['update'].post(doc.to_xml, :content_type => 'application/xml')
|
41
|
+
end
|
42
|
+
pids
|
43
|
+
end
|
44
|
+
|
45
|
+
def risearch(query, opts = {})
|
46
|
+
client = Config.fedora.client['risearch']
|
47
|
+
client.options[:timeout] = opts.delete(:timeout)
|
48
|
+
query_params = {
|
49
|
+
:type => 'tuples',
|
50
|
+
:lang => 'itql',
|
51
|
+
:format => 'CSV',
|
52
|
+
:limit => '1000',
|
53
|
+
:stream => 'on',
|
54
|
+
:query => query
|
55
|
+
}.merge(opts)
|
56
|
+
result = client.post(query_params)
|
57
|
+
result.split(/\n/)[1..-1].collect { |pid| pid.chomp.sub(/^info:fedora\//,'') }
|
58
|
+
end
|
59
|
+
|
60
|
+
def gsearch(params)
|
61
|
+
client = Config.gsearch.client
|
62
|
+
query_params = params.merge(:wt => 'json')
|
63
|
+
query_string = query_params.collect { |k,v|
|
64
|
+
if v.is_a?(Array)
|
65
|
+
v.collect { |vv| "#{k}=#{URI.encode(vv.to_s)}" }.join('&')
|
66
|
+
else
|
67
|
+
"#{k}=#{URI.encode(v.to_s)}"
|
68
|
+
end
|
69
|
+
}.join('&')
|
70
|
+
result = JSON.parse(client["select?#{query_string}"].get)
|
71
|
+
end
|
72
|
+
|
73
|
+
def query_by_id(id)
|
74
|
+
if id.is_a?(Hash) # Single valued: { :google => 'STANFORD_0123456789' }
|
75
|
+
id = id.collect { |*v| v.join(':') }.first
|
76
|
+
elsif id.is_a?(Array) # Two values: [ 'google', 'STANFORD_0123456789' ]
|
77
|
+
id = id.join(':')
|
78
|
+
end
|
79
|
+
self.risearch(RISEARCH_TEMPLATE % id)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
require 'active_fedora'
|
3
|
+
|
4
|
+
module Dor
|
5
|
+
class SuriService
|
6
|
+
|
7
|
+
Config.declare(:suri) do
|
8
|
+
url nil
|
9
|
+
user nil
|
10
|
+
pass nil
|
11
|
+
id_namespace 'druid'
|
12
|
+
mint_ids false
|
13
|
+
end
|
14
|
+
|
15
|
+
# If Dor::Config.suri.mint_ids is set to true, then this method
|
16
|
+
# returns Config.suri.id_namespace:id_from_suri
|
17
|
+
# Throws an exception if there were any problems
|
18
|
+
def self.mint_id
|
19
|
+
unless(Config.suri.mint_ids)
|
20
|
+
return Fedora::Repository.instance.nextid
|
21
|
+
end
|
22
|
+
|
23
|
+
#Post with no body
|
24
|
+
resource = RestClient::Resource.new("#{Config.suri.url}/suri2/namespaces/#{Config.suri.id_namespace}/identifiers",
|
25
|
+
:user => Config.suri.user, :password => Config.suri.pass)
|
26
|
+
id = resource.post('').chomp
|
27
|
+
|
28
|
+
return "#{Config.suri.id_namespace}:#{id.strip}"
|
29
|
+
|
30
|
+
# rescue Exception => e
|
31
|
+
# Rails.logger.error("Unable to mint id from suri: #{e.to_s}")
|
32
|
+
# raise e
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/dor/tei2dc.xslt
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
3
|
+
xmlns:tei="http://www.tei-c.org/ns/1.0"
|
4
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
5
|
+
xmlns:dcterms="http://purl.org/dc/terms/"
|
6
|
+
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
|
7
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
8
|
+
exclude-result-prefixes="tei xsl"
|
9
|
+
version="1.0">
|
10
|
+
|
11
|
+
<xsl:output xml:space="default" indent="yes"/>
|
12
|
+
|
13
|
+
<xsl:template match="/">
|
14
|
+
<oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
|
15
|
+
<xsl:apply-templates/>
|
16
|
+
</oai_dc:dc>
|
17
|
+
</xsl:template>
|
18
|
+
|
19
|
+
<xsl:template match="tei:teiHeader">
|
20
|
+
<xsl:apply-templates/>
|
21
|
+
</xsl:template>
|
22
|
+
|
23
|
+
<xsl:template match="tei:fileDesc/tei:titleStmt/tei:title">
|
24
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:title</xsl:with-param></xsl:call-template>
|
25
|
+
</xsl:template>
|
26
|
+
|
27
|
+
<xsl:template match="tei:fileDesc/tei:titleStmt/tei:author">
|
28
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:creator</xsl:with-param></xsl:call-template>
|
29
|
+
</xsl:template>
|
30
|
+
|
31
|
+
<xsl:template match="tei:profileDesc/tei:textClass/tei:keywords/tei:list/tei:item">
|
32
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:subject</xsl:with-param></xsl:call-template>
|
33
|
+
</xsl:template>
|
34
|
+
|
35
|
+
<xsl:template match="tei:encodingDesc/tei:refsDecl|tei:encodingDesc/tei:projectDesc|tei:encodingDesc/tei:editorialDesc">
|
36
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:description</xsl:with-param></xsl:call-template>
|
37
|
+
</xsl:template>
|
38
|
+
|
39
|
+
<xsl:template match="tei:fileDesc/tei:publicationStmt/tei:publisher/tei:publisher|tei:fileDesc/tei:publicationStmt/tei:publisher/tei:pubPlace">
|
40
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:publisher</xsl:with-param></xsl:call-template>
|
41
|
+
</xsl:template>
|
42
|
+
|
43
|
+
<xsl:template match="tei:fileDesc/tei:titleStmt/tei:editor|tei:fileDesc/tei:titleStmt/tei:funder|tei:fileDesc/tei:titleStmt/tei:sponsor|tei:fileDesc/tei:titleStmt/tei:principle">
|
44
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:contributor</xsl:with-param></xsl:call-template>
|
45
|
+
</xsl:template>
|
46
|
+
|
47
|
+
<xsl:template match="tei:fileDesc/tei:publicationStmt/tei:date">
|
48
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:date</xsl:with-param></xsl:call-template>
|
49
|
+
</xsl:template>
|
50
|
+
|
51
|
+
<xsl:template match="tei:extent/tei:seg[@type='size']">
|
52
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dcterms:extent</xsl:with-param></xsl:call-template>
|
53
|
+
</xsl:template>
|
54
|
+
|
55
|
+
<xsl:template match="tei:fileDesc/tei:publicationStmt/tei:idno[@type='ARK']">
|
56
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:identifier</xsl:with-param></xsl:call-template>
|
57
|
+
</xsl:template>
|
58
|
+
|
59
|
+
<xsl:template match="tei:sourceDesc/tei:bibful/tei:publicationStmt/tei:publisher|tei:sourceDesc/tei:bibful/tei:publicationStmt/tei:pubPlace|tei:sourceDesc/tei:bibful/tei:publicationStmt/tei:date|tei:sourceDesc/tei:bibl">
|
60
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:source</xsl:with-param></xsl:call-template>
|
61
|
+
</xsl:template>
|
62
|
+
|
63
|
+
<xsl:template match="tei:profileDesc/tei:langUsage/tei:language">
|
64
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:language</xsl:with-param></xsl:call-template>
|
65
|
+
</xsl:template>
|
66
|
+
|
67
|
+
<xsl:template match="tei:fileDesc/tei:seriesStmt/tei:title">
|
68
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dc:relation</xsl:with-param></xsl:call-template>
|
69
|
+
</xsl:template>
|
70
|
+
|
71
|
+
<xsl:template match="tei:fileDesc/tei:publicationStmt/tei:availability">
|
72
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dcterms:accessRights</xsl:with-param></xsl:call-template>
|
73
|
+
</xsl:template>
|
74
|
+
|
75
|
+
<xsl:template match="tei:notesStmt/tei:note[@type='summary']">
|
76
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dcterms:abstract</xsl:with-param></xsl:call-template>
|
77
|
+
</xsl:template>
|
78
|
+
|
79
|
+
<!--
|
80
|
+
<xsl:template match="tei:notesStmt/tei:note[not(@type)]">
|
81
|
+
<xsl:call-template name="ptext"><xsl:with-param name="element-name">dcterms:note</xsl:with-param></xsl:call-template>
|
82
|
+
</xsl:template>
|
83
|
+
-->
|
84
|
+
|
85
|
+
<xsl:template name="ptext">
|
86
|
+
<xsl:param name="element-name"/>
|
87
|
+
<xsl:variable name="text">
|
88
|
+
<xsl:for-each select=".|./tei:p">
|
89
|
+
<xsl:variable name="t" select="normalize-space(./text())"/>
|
90
|
+
<xsl:if test="string-length($t) > 0">
|
91
|
+
<xsl:value-of select="$t"/>
|
92
|
+
</xsl:if>
|
93
|
+
</xsl:for-each>
|
94
|
+
</xsl:variable>
|
95
|
+
<xsl:if test="string-length($text) > 0">
|
96
|
+
<xsl:element name="{$element-name}"><xsl:value-of select="$text"/></xsl:element>
|
97
|
+
</xsl:if>
|
98
|
+
</xsl:template>
|
99
|
+
|
100
|
+
<xsl:template match="text()|@*"/>
|
101
|
+
|
102
|
+
</xsl:stylesheet>
|