Given an RDF::URI
and a SPARQL property path (stored as a String), I want to find values that satisfy the following query
SELECT ?value WHERE {
<URI> <property_path> ?value .
}
I managed to get by using the following snippet, but is feels very hackish:
query = SPARQL.parse(<<~QUERY)
SELECT ?value WHERE {
<#{uri}> #{property_path} ?value
}
QUERY
graph.query(query)
Is there a better way to achieve this, using a RDF::Query
for example?
From my understanding, you consider string interpolation to be "hackish" because you would like to deal with "things, not strings". This desire is definitely not reprehensible in a Semantic Web related field.
If so, you could construct queries using SPARQL::Algebra
.
All snippets below have the same meaning:
SPARQL query (q1
)
SELECT ?value WHERE {
<http://example.org/green-goblin>
<http://www.w3.org/2000/01/rdf-schema#label>|<http://xmlns.com/foaf/0.1/name>
?value .
}
SPARQL Algebra expression (q2
)
(project
?value
(path
<http://example.org/green-goblin>
(alt
<http://www.w3.org/2000/01/rdf-schema#label>
<http://xmlns.com/foaf/0.1/name>
)
?value
)
)
Ruby code (q3
)
Operator::Project.new(
Variable(:value),
Operator::Path.new(
RDF::URI('http://example.org/green-goblin'),
Operator::Alt.new(
RDF::URI('http://www.w3.org/2000/01/rdf-schema#label'),
RDF::URI('http://xmlns.com/foaf/0.1/name')
),
Variable(:value)
)
)
Compare internal representations or queries results:
require 'rubygems'
require 'sparql'
require 'sparql/algebra'
include SPARQL::Algebra
query1 = SPARQL.parse(q1)
query2 = SPARQL::Algebra::Expression.parse(q2)
query3 = eval(q3)
puts query1.to_sxp
puts query2.to_sxp
puts query3.to_sxp
query1.execute(queryable) do |result|
puts result.inspect
end
query2.execute(queryable) do |result|
puts result.inspect
end
query3.execute(queryable) do |result|
puts result.inspect
end
The difference is that you do not need string manipulations in the third case.
These "operators" even have URIs (e.g. Operator[:project]
).