Permalink
Browse files

Agents should be modeled a little better

  • Loading branch information...
1 parent f909b4b commit f8f95630b7c777d1ba7ea3087677e4fdd1b4b1f2 @rsinger committed Aug 17, 2009
Showing with 23,455 additions and 41 deletions.
  1. +23,087 −0 example.ttl
  2. +123 −38 marcmodeler.rb
  3. +13 −3 rdf_resource.rb
  4. +232 −0 relation.yml
View
23,087 example.ttl
23,087 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
161 marcmodeler.rb
@@ -33,6 +33,7 @@ class MARC::Record
@@base_uri = 'http://library.cca.edu/core'
@@missing_id_prefix = 'cca'
@@missing_id_counter = 0
+ @@relators = YAML::load_file('relation.yml')
def subdivided?(subject)
subject.subfields.each do | subfield |
@@ -145,23 +146,23 @@ def to_rdf_resources
if subject.tag =~ /^(600|610|696|697)$/
if !subdivided?(subject)
- concept = RDFResource.new("#{@@base_uri}/i/#{literal.slug}#concept")
- identity = RDFResource.new("#{@@base_uri}/i/#{literal.slug}")
+ concept = RDFResource.new("#{@@base_uri}/#{Identity.path(subject)}/#{literal.slug}#concept")
+ identity = RDFResource.new("#{@@base_uri}/#{Identity.path(subject)}/#{literal.slug}")
else
- concept = RDFResource.new("#{@@base_uri}/s/#{literal.slug}#concept")
+ concept = RDFResource.new("#{@@base_uri}/subjects/#{literal.slug}#concept")
identity_subject = top_concept(subject)
- identity = RDFResource.new("#{@@base_uri}/i/#{subject_to_string(identity_subject).slug}")
+ identity = RDFResource.new("#{@@base_uri}/#{Identity.path(subject)}/#{subject_to_string(identity_subject).slug}")
end
if subject.tag =~ /^(600|696)$/
identity.relate("[rdf:type]","[foaf:Person]")
if subject['u']
- identity.assert("[ov:affiliation]", subject['u'].sub)
+ identity.assert("[ov:affiliation]", subject['u'].strip_trailing_punct)
end
- concept.relate("[skos:inScheme]", "#{@@base_uri}/s#personalNames")
+ concept.relate("[skos:inScheme]", "#{@@base_uri}/subjects#personalNames")
else
identity.relate("[rdf:type]","[foaf:Organization]")
identity.assert("[dct:description]", subject['u'])
- concept.relate("[skos:inScheme]", "#{@@base_uri}/s#corporateNames")
+ concept.relate("[skos:inScheme]", "#{@@base_uri}/subjects#corporateNames")
end
concept.relate("[rdfs:seeAlso]", identity.uri)
identity.relate("[rdfs:seeAlso]", concept.uri)
@@ -176,12 +177,12 @@ def to_rdf_resources
resources << identity
elsif subject.tag =~ /^(611|698)$/
if !subdivided?(subject)
- concept = RDFResource.new("#{@@base_uri}/e/#{literal.slug}#concept")
- event = RDFResource.new("#{@@base_uri}/e/#{literal.slug}")
+ concept = RDFResource.new("#{@@base_uri}/events/#{literal.slug}#concept")
+ event = RDFResource.new("#{@@base_uri}/events/#{literal.slug}")
else
- concept = RDFResource.new("#{@@base_uri}/s/#{literal.slug}#concept")
+ concept = RDFResource.new("#{@@base_uri}/subjects/#{literal.slug}#concept")
event_subject = top_concept(subject)
- event = RDFResource.new("#{@@base_uri}/e/#{subject_to_string(event_subject).slug}")
+ event = RDFResource.new("#{@@base_uri}/events/#{subject_to_string(event_subject).slug}")
end
concept.relate("[skos:inScheme]", "#{@@base_uri}/s#meetings")
event.relate("[rdf:type]","[event:Event]")
@@ -249,6 +250,7 @@ def to_rdf_resources
end
end
resources << concept
+ manifestation.relate("[dct:subject]", concept.uri)
end
authority = false
end
@@ -266,21 +268,65 @@ def to_rdf_resources
if self.form
manifestation.assert("[dc:format]", self.form(true))
end
- if self['100']
- identity = Identity.new_from_field(self['100'], "#{@@base_uri}/i/")
- end
- persons = self.find_all{|field| field.tag =~ /700|100|800|600|896|790|690/ && (field['e'] || field['4'])}
- persons.each do | person |
- if person['e']
- puts "$e: #{person['e']}"
- end
- if person['4']
- puts "$4: #{person['4']}"
- end
- end
+ identities = self.find_all{|field| field.tag =~ /100|110|400|410|700|710|720|790|791|796|797|800|810|896|897/}
+ identities.each do | identity_field |
+ identity = Identity.new_from_field(identity_field, "#{@@base_uri}/")
+ resources << identity.resource
+ relate_identity(identity_field, manifestation, identity)
+ end
+
+ meetings = self.find_all{|field| field.tag =~ /111|411|711|792|798|811|898/}
+ meetings.each do | meeting |
+ identity = Identity.new_from_field(identity_field, "#{@@base_uri}/events/")
+ resources << identity.resource
+ relate_identity(identity_field, manifestation, identity)
+ end
resources
end
+
+ def relate_identity(datafield, resource, identity)
+ if ["100","110"].index(datafield.tag)
+ resource.relate("[dct:creator]", identity.resource.uri)
+ resource.assert("[dc:creator]",identity.name)
+ end
+ relationships = []
+ datafield.subfields.each do | subfield |
+ next unless subfield.code == 'e' || subfield.code == '4'
+ next unless @@relators[subfield.value.strip_trailing_punct]
+ if pointer = @@relators[subfield.value.strip_trailing_punct]["use"]
+ if @@relators[subfield.value.strip_trailing_punct]["use"].is_a?(Array)
+ @@relators[subfield.value.strip_trailing_punct]["use"].each {|u| relationships << @@relators[u] }
+ else
+ relationships << @@relators[pointer]
+ end
+ else
+ relationships << @@relators[subfield.value.strip_trailing_punct]
+ end
+ end
+
+ unless relationships.empty?
+ relationships.uniq.each do | rel |
+ if rel["relationship"]
+ if rel["relationship"].is_a?(Array)
+ rel["relationship"].each do | r |
+ resource.relate(r, identity.resource.uri)
+ end
+ else
+ resource.relate(rel['relationship'], identity.resource.uri)
+ end
+ end
+ if rel["literal"]
+ resource.assert(rel['literal'], identity.name)
+ end
+ end
+ else
+ unless ["100","110"].index(datafield.tag)
+ resource.relate("[dct:contributor]", identity.resource.uri)
+ resource.assert("[dc:contributor]", identity.resource.name)
+ end
+ end
+ end
end
class MARC::BookRecord
@@ -312,23 +358,32 @@ def [](code)
end
class Identity
+ attr_accessor :name, :resource
def self.new_from_field(field, base_uri)
+ identity = self.new
name = ''
- if field.tag == '100'
- name << field['a'].strip_trailing_punct
+
+ personal = ["100","400","700","790","796", "800","896"]
+ corporate = ["110","410","710","791","797", "810", "897"]
+
+ if personal.index(field.tag)
+ name << field['a']
['b','c','d','q'].each do | code |
- name << field[code].lpad.strip_trailing_punct if field[code]
+ name << field[code].lpad if field[code]
end
- elsif field.tag == '110'
+ elsif corporate.index(field.tag)
name << field['a'].strip_trailing_punct
['b','c','d'].each do | code |
- name << field[code].lpad.strip_trailing_punct if field[code]
+ name << field[code].lpad if field[code]
end
- end
- resource = RDFResource.new("#{base_uri}#{name.slug}")
- if field.tag == '100'
+ elsif field.tag == "720"
+ name = field['a'].strip_trailing_punct
+ end
+ identity.name = name.strip_trailing_punct
+ resource = RDFResource.new("#{base_uri}#{self.path(field)}/#{name.slug}")
+ if personal.index(field.tag)
resource.relate("[rdf:type]", "[foaf:Person]")
- if field.indicator1 == "2"
+ if field.indicator1 == "1"
last,first = field['a'].strip_trailing_punct.split(", ")
if last && first
resource.assert("[foaf:surname]", last)
@@ -338,16 +393,44 @@ def self.new_from_field(field, base_uri)
if field['q']
resource.assert("[dct:alternate]", field['q'].strip_leading_and_trailing_punct)
end
- elsif field.tag == '110'
+ if field['u']
+ resource.assert("[ov:affiliation]", field['u'].strip_trailing_punct)
+ end
+ elsif corporate.index(field.tag)
resource.relate("[rdf:type]", "[foaf:Organization]")
+ if field['u']
+ resource.assert("[dct:description]", field['u'].strip_trailing_punct)
+ end
+ elsif field.tag == "720"
+ if field.indicator1 == "1"
+ resource.relate("[rdf:type]", "[foaf:Person]")
+ else
+ resource.relate("[rdf:type]", "[foaf:Agent]")
+ end
end
resource.assert("[foaf:name]", field['a'].strip_trailing_punct)
if field['d']
resource.assert("[dct:date]", field['d'])
end
- resource
+ identity.resource = resource
+ identity
end
-
+ def self.path(datafield)
+ personal = ["100","400", "600","696","700","790","796", "800","896"]
+ corporate = ["110","410", "610", "697","710","791","797", "810", "897"]
+ if personal.index(datafield.tag)
+ return "people"
+ elsif corporate.index(datafield.tag)
+ return "organizations"
+ elsif datafield.tag == "720"
+ if datafield.indicator1 == "1"
+ return "people"
+ else
+ return "agents"
+ end
+ end
+ end
+
def self.relations(field)
end
@@ -380,8 +463,10 @@ def self.relations(field)
reader.each do | record |
@resources += record.to_rdf_resources
i += 1
- #break if i > 1000
+ break if i > 1000
end
+puts "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">"
@resources.each do | resource |
- #puts resource.to_rdfxml
-end
+ puts resource.to_rdfxml
+end
+puts "</rdf:RDF>"
View
16 rdf_resource.rb
@@ -7,15 +7,25 @@ class RDFResource
def initialize(uri)
Curie.add_prefixes! :frbr=>"http://vocab.org/frbr/core#", :dct=>"http://purl.org/dc/terms/", :bibo=>"http://purl.org/ontology/bibo/",
:skos=>"http://www.w3.org/2004/02/skos/core#", :rda=>"http://RDVocab.info/Elements/", :cat=>"http://schema.talis.com/2009/catalontology/",
- :rdfs=>"http://www.w3.org/2000/01/rdf-schema#", :ov=>"http://open.vocab.org/terms/", :event=>"http://purl.org/NET/c4dm/event.owl#"
- @uri = Curie.parse uri
+ :rdfs=>"http://www.w3.org/2000/01/rdf-schema#", :ov=>"http://open.vocab.org/terms/", :event=>"http://purl.org/NET/c4dm/event.owl#",
+ :role=>"http://RDVocab.info/roles/", :mo=>"http://purl.org/ontology/mo/", :rdf=>'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
+
+ if uri.could_be_a_safe_curie?
+ @uri = Curie.parse uri
+ else
+ @uri = uri
+ end
@namespaces = ['http://www.w3.org/1999/02/22-rdf-syntax-ns#']
@modifiers = {}
end
def assert(predicate, object, type=nil, lang=nil)
- uri = URI.parse(Curie.parse predicate)
+ if predicate.could_be_a_safe_curie?
+ uri = URI.parse(Curie.parse predicate)
+ else
+ uri = URI.parse(predicate)
+ end
ns = nil
elem = nil
if uri.fragment
View
232 relation.yml
@@ -0,0 +1,232 @@
+---
+dst:
+ label: Distributor
+ relationship: "[bibo:distributor]"
+
+music:
+ use: intr
+ed:
+ label: Editor
+ relationship: "[bibo:editor]"
+ multiple: "[bibo:editorList]"
+ literal: "[dc:contributor]"
+illus:
+ label: Illustrator
+ relationship: "[role:illustrator]"
+ literal: "[dc:contributor]"
+dedicatee:
+ label: Dedicatee
+ relationship: "[role:dedicatee]"
+printer:
+ use: prt
+intr:
+ label: Instrumentalist
+ relationship: "[role:instrumentalist]"
+ literal: "[dc:contributor]"
+nrt:
+ label: Narrator
+ relationship: "[role:narrator]"
+ literal: "[dc:contributor]"
+artist, illus:
+ use: illus
+jt. comp:
+ use: comp
+prt:
+ label: Printer
+ relationship: "[role:printer]"
+translator:
+ use: tr
+ed. and tr:
+ use:
+ - ed
+ - translator
+pbl:
+ label: Publisher
+ relationship: "[dct:publisher]"
+ literal: "[dc:publisher]"
+cover designer:
+ label: Cover Designer
+ relationship: "[role:designer]"
+artist:
+ label: Artist
+ relationship: "[role:artist]"
+ literal: "[dc:contributor]"
+fot:
+hst:
+ label: Host
+ relationship: "[role:host]"
+ literal: "[dc:contributor]"
+act:
+ label: Actor
+ relationship: "[role:actor]"
+ literal: "[dc:contributor]"
+editor:
+ use: ed
+arr:
+ label: Arranger
+ relationship: "[role:arrangerOfMusic]"
+ literal: "[dc:contributor]"
+trans:
+ use: tr
+prd:
+ label: Production personnel
+ relationship: "[dct:contributor]"
+art:
+ use: artist
+joint illus:
+ use: illus
+camera operator:
+ label: Videographer
+ relationship: "[role:cinematographer]"
+ctb:
+ label: Contributor
+ relationship: "[dct:contributor]"
+ literal: "[dc:contributor]"
+coaut:
+ use: aut
+annotator:
+ label: Annotator
+ relationship: "[role:annotator]"
+ literal: "[dc:contributor]"
+flm:
+ label: Film editor
+ relationship: "[role:editorOfMovingImageWork]"
+pht:
+ label: Photographer
+ relationship: "[role:photographer]"
+ literal: "[dc:contributor]"
+Co-auteur:
+ use: aut
+prf:
+ label: Performer
+ relationship: "[role:performer]"
+ literal: "[dc:contributor]"
+Translator:
+ use: tr
+joint compiler:
+ use: com
+com:
+ label: Compiler
+ relationship: "[role:compiler]"
+ill:
+ use: illus
+illustrator:
+ use: illus
+drt:
+ label: Director
+ relationship: "[role:filmDirector]"
+ literal: "[dc:contributor]"
+adp:
+ label: Adapter
+ relationship: "[dct:contributor]"
+ literal: "[dc:contributor]"
+donor:
+ label: Donor
+ relationship: "[role:donor]"
+defendant:
+ label: Defendant
+ relationship: "[role:defendant]"
+architects:
+ label: Architect
+ relationship: "[role:architect]"
+jt. ed:
+ use: ed
+bookjacket designer:
+ label: Bookjacket designer
+ relationship: "[role:designer]"
+research:
+ label: Researcher
+ relationship: "[dct:contributor]"
+cnd:
+ label: Conductor
+ relationship: "[role:conductor]"
+ literal: "[dc:contributor]"
+aus:
+ label: Screenwriter
+ relationship: "[role:screenwriter]"
+jt. au:
+ use: aut
+book designer:
+ label: Book designer
+ relationship: "[role:bookDesigner]"
+joint comp:
+ use: cmp
+cmm:
+ label: Commentator
+ relationship: "[role:commentator]"
+ literal: "[dc:contributor]"
+cur:
+ label: Curator of an Exhibition
+ relationship: "[role:curator]"
+ literal: "[dc:contributor]"
+photographer:
+ use: pht
+bookbinder:
+ label: Binder
+ relationship: "[role:binder]"
+comp. and illus:
+ use:
+ - com
+ - illus
+sgn:
+ label: Signer
+ relationship: "[role:signer]"
+aut:
+ label: Author
+ relationship: "[dct:creator]"
+ literal: "[dc:creator]"
+jt. auth:
+ use: aut
+publisher:
+ use: pbl
+cng:
+ label: Cinematographer
+ relationship: "[role:directorOfPhotography]"
+ literal: "[dc:contributor]"
+joint tr:
+ use: tr
+ive:
+ label: Interviewee
+ relationship:
+ - "[bibo:interviewee]"
+ - "[role:interviewee]"
+ literal: "[dc:contributor]"
+aud:
+ label: Author of dialog
+ relationship: "[dct:contributor]"
+ literal: "[dc:contributor]"
+spk:
+ label: Speaker
+ relationship: "[role:speaker]"
+tr:
+ label: Translator
+ relationship:
+ - "[bibo:translator]"
+ - "[role:translator]"
+ literal: "[dc:contributor]"
+bkp:
+ label: Book producer
+ relationship: "[role:producer]"
+ literal: "[dc:publisher]"
+cmp:
+ label: Composer
+ relationship: "[role:composer]"
+ literal: "[dc:contributor]"
+comp:
+ use: cmp
+pro:
+ label: Producer
+ relationship:
+ - "[bibo:producer]"
+ - "[role:filmProducer]"
+ literal: "[dc:contributor]"
+comp. and tr:
+ use:
+ - com
+ - tr
+edt:
+ use: ed
+trl:
+ use: tr
+binder:
+ use: bookbinder

0 comments on commit f8f9563

Please sign in to comment.