Skip to content

Commit 3c84075

Browse files
committed
Improve heuristics for generating term statements based on value inspection.
1 parent 09de5f4 commit 3c84075

2 files changed

Lines changed: 98 additions & 2 deletions

File tree

lib/rdf/vocabulary.rb

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,25 @@ def each_statement
625625
else
626626
prop = RDF::Vocabulary.expand_pname(prop.to_s)
627627
next unless prop
628-
v = RDF::Vocabulary.expand_pname(value.to_s)
629-
value = v.valid? ? v : RDF::Literal(value.to_s)
628+
629+
v = value.to_s
630+
value = RDF::Vocabulary.expand_pname(v)
631+
unless value && value.valid?
632+
require 'byebug'; byebug if prop.to_s.include?('isDefinedBy')
633+
# Use as most appropriate literal
634+
value = [
635+
RDF::Literal::Date,
636+
RDF::Literal::DateTime,
637+
RDF::Literal::Integer,
638+
RDF::Literal::Decimal,
639+
RDF::Literal::Double,
640+
RDF::Literal::Boolean,
641+
RDF::Literal
642+
].inject(nil) do |memo, klass|
643+
l = klass.new(v)
644+
memo || (l if l.valid?)
645+
end
646+
end
630647
end
631648
yield RDF::Statement(self, prop, value)
632649
rescue KeyError

spec/vocabulary_spec.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,5 +349,84 @@
349349
its(:attributes) {is_expected.to include("schema:domainIncludes" => RDF::RDFS.Resource)}
350350
its(:attributes) {is_expected.to include("schema:rangeIncludes" => [RDF::RDFS.Resource, RDF::RDFS.Class])}
351351
end
352+
353+
context "#each_statement" do
354+
it "emits statements for a vocabulary" do
355+
graph = RDF::Graph.new {|g| RDF::RDFS[""].each_statement {|s| g << s}}
356+
357+
expect(graph.map(&:subject)).to all(eql(RDF::RDFS.to_uri))
358+
expect(graph.query(predicate: RDF.type).map(&:object)).to include RDF::OWL.Ontology
359+
end
360+
361+
{
362+
"rdfs:comment" => {term: RDF::RDFS.comment, predicate: RDF::RDFS.comment, value: RDF::Literal(%(A description of the subject resource.))},
363+
"rdfs:label" => {term: RDF::RDFS.label, predicate: RDF::RDFS.label, value: RDF::Literal("label")},
364+
"rdf:type" => {term: RDF.type, predicate: RDF.type, value: RDF.Property},
365+
"rdfs:subClassOf" => {term: RDF::RDFS.Class, predicate: RDF::RDFS.subClassOf, value: RDF::RDFS.Resource},
366+
"rdfs:subPropertyOf" => {term: RDF::RDFS.isDefinedBy, predicate: RDF::RDFS.subPropertyOf, value: RDF::RDFS.seeAlso},
367+
"rdfs:domain" => {term: RDF::RDFS.domain, predicate: RDF::RDFS.domain, value: RDF.Property},
368+
"rdfs:range" => {term: RDF::RDFS.range, predicate: RDF::RDFS.range, value: RDF::RDFS.Class},
369+
"schema:domainIncludes" => {
370+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {domainIncludes: RDF::RDFS.Resource}),
371+
predicate: RDF::Vocab::SCHEMA.domainIncludes,
372+
value: RDF::RDFS.Resource
373+
},
374+
"schema:inverseOf" => {
375+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {inverseOf: RDF::RDFS.Resource}),
376+
predicate: RDF::Vocab::SCHEMA.inverseOf,
377+
value: RDF::RDFS.Resource
378+
},
379+
"schema:rangeIncludes" => {
380+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {rangeIncludes: RDF::RDFS.Resource}),
381+
predicate: RDF::Vocab::SCHEMA.rangeIncludes,
382+
value: RDF::RDFS.Resource
383+
},
384+
"vocab value" => {term: RDF::RDFS.isDefinedBy, predicate: RDF::RDFS.isDefinedBy, value: RDF::RDFS.to_uri},
385+
"term value" => {
386+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdfs:seeAlso" => "rdfs:seeAlso"}),
387+
predicate: RDF::RDFS.seeAlso,
388+
value: RDF::RDFS.seeAlso
389+
},
390+
"uri value" => {term: RDF::RDFS[""], predicate: RDF::RDFS.seeAlso, value: RDF::URI("http://www.w3.org/2000/01/rdf-schema-more")},
391+
"date value" => {
392+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "2016-04-24"}),
393+
predicate: RDF.value,
394+
value: RDF::Literal::Date.new("2016-04-24")
395+
},
396+
"dateTime value" => {
397+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "2016-04-24T15:22:00"}),
398+
predicate: RDF.value,
399+
value: RDF::Literal::DateTime.new("2016-04-24T15:22:00")
400+
},
401+
"boolean value" => {
402+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "true"}),
403+
predicate: RDF.value,
404+
value: RDF::Literal::Boolean.new(true)
405+
},
406+
"integer value" => {
407+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "1"}),
408+
predicate: RDF.value,
409+
value: RDF::Literal::Integer.new(1)
410+
},
411+
"decimal value" => {
412+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "1.1"}),
413+
predicate: RDF.value,
414+
value: RDF::Literal::Decimal.new(1.1)
415+
},
416+
"double value" => {
417+
term: RDF::Vocabulary::Term.new(:foo, label: "foo", attributes: {:"rdf:value" => "1.1e1"}),
418+
predicate: RDF.value,
419+
value: RDF::Literal::Double.new(1.1e1)
420+
},
421+
"literal value" => {term: RDF::RDFS[""], predicate: RDF::Vocab::DC11.title, value: RDF::Literal("The RDF Schema vocabulary \(RDFS\)")},
422+
}.each do |pred, props|
423+
it "emits #{pred}" do
424+
graph = RDF::Graph.new {|g| props[:term].each_statement {|s| g << s}}
425+
426+
expect(graph.map(&:subject)).to all(eql(props[:term]))
427+
expect(graph.query(predicate: props[:predicate]).map(&:object)).to include props[:value]
428+
end
429+
end
430+
end
352431
end
353432
end

0 commit comments

Comments
 (0)