This morning at Access during the Hackfest report I went on after Bess Sadler, who talked about the work she and Lisa Goddard did figuring out Ross Singer's marc2rdf-modeler. Here's what I said.
- I listed the four things about Linked Data.
- I said RDF is about subject-predicate-object relationships. "This conference hasName Access" and "This conference hasLocation Charlottetown." Not scintillating conversation but a straightforward way of stating facts.
- If you do all this then you end up being part of the big web of data illustrated on the Linked Data page. I need some data in that web for OpenFRBR, from Freebase, id.loc.gov, etc. How can I get to it with Ruby?
- Let's do an example. Take the LCSH authority record for Cider. I have the URI for that ...
- and I have the URI for broader term thanks to SKOS ...
- so how can I use Ruby to go from the URI for Cider to the URI for its broader term? I have the subject (Cider), the predicate (has broader term), and URIs for both. How do I get the URI for actual broader term? I can see with my eye it's "Fruit wines" but I want to do it in Ruby.
- I did it using Ruby bindings for Redland.
It took me all afternoon but eventually I figured this out:
$ irb irb(main):001:0> require 'rdf/redland' => true irb(main):002:0> cider_uri = Redland::Uri.new("http://id.loc.gov/authorities/sh85025940#concept") => #<Redland::Uri:0xb7c58854 @uri=#<SWIG::TYPE_p_librdf_uri_s:0xb7c5882c>> irb(main):003:0> broader_uri = Redland::Uri.new("http://www.w3.org/2004/02/skos/core#broader") => #<Redland::Uri:0xb7c54074 @uri=#<SWIG::TYPE_p_librdf_uri_s:0xb7c5404c>> irb(main):004:0> prefLabel_uri = Redland::Uri.new("http://www.w3.org/2004/02/skos/core#prefLabel") => #<Redland::Uri:0xb7c4f6f0 @uri=#<SWIG::TYPE_p_librdf_uri_s:0xb7c4f6c8>> irb(main):005:0> storage=Redland::TripleStore.new("hashes", "test", "new='yes',hash-type='memory',dir='.'") => #<Redland::TripleStore:0xb7c4a448 @store=#<SWIG::TYPE_p_librdf_storage_s:0xb7c4a3f8>,@store_type="hashes", @name="test"> irb(main):006:0> model=Redland::Model.new(storage) => #<Redland::Model:0xb7c47a68 @model=#<SWIG::TYPE_p_librdf_model_s:0xb7c47a18>, @store=#<Redland::TripleStore:0xb7c4a448 @store=#<SWIG::TYPE_p_librdf_storage_s:0xb7c4a3f8>, @store_type="hashes", @name="test">, @statements=[]> irb(main):007:0> parser=Redland::Parser.new("raptor", "", nil) => #<Redland::Parser:0xb7c44200 @context=nil, @parser=#<SWIG::TYPE_p_librdf_parser_s:0xb7c441c4>, @idents=[]> irb(main):008:0> model.size => 0 irb(main):009:0> parser.parse_into_model(model, cider_uri) => 0 irb(main):010:0> model.size => 14 irb(main):011:0> model.object(cider_uri, prefLabel_uri).to_s => "Cider@en" irb(main):012:0> object_uri = model.object(cider_uri, broader_uri).uri => #<Redland::Uri:0xb7c399b8 @uri=#<SWIG::TYPE_p_librdf_uri_s:0xb7c39990>> irb(main):013:0> object_uri.to_s => "http://id.loc.gov/authorities/sh85052187#concept" irb(main):014:0> parser.parse_into_model(model, object_uri) => 0 irb(main):015:0> model.size => 27 irb(main):016:0> model.object(object_uri, prefLabel_uri).to_s => "Fruit wines@en"
With that, I move from piece of linked data to another, parse it, and pick out the piece of information I want. Now everything in the web of linked data is available to me.