I want to query RDF lists (also known as RDF collections) using SPARQL.
What are my options?
I want to query RDF lists (also known as RDF collections) using SPARQL.
What are my options?
Options vary depending on whether you have SPARQL, SPARQL 1.1, or even what engine you use.
You can only bind fixed-length RDF lists in a single SPARQL 1 query:
PREFIX ...
SELECT *
WHERE {
?u owl:unionOf ( ?el1 ?el2 ) .
}
...which is just a shortcut for:
PREFIX ...
SELECT *
WHERE {
?u owl:unionOf [
rdf:first ?el1 ;
rdf:rest [
rdf:first ?el2 ;
rdf:rest rdf:nil ]
] .
}
Obviously you can extend this to a list of any fixed length. This also preserves the original ordering of the list.
If you use multiple SPARQL 1 queries, you can load arbitrary length lists. For example, you can just use the fixed length syntax above repeatedly for increasing size until you get what you want. Obviously that's not a great idea.
Instead you could traverse the list in a loop (pseudo-pseudo-code):
members := {}
evaluate (PREFIX ... SELECT ?list WHERE { ?u owl:unionOf ?list })
while(?list != rdf:nil) {
evaluate (PREFIX ... SELECT ?f ?l WHERE { ?list rdf:first ?el ; rdf:rest ?l })
members.add(?el)
?l := ?list
}
This would be fine, but would require n
queries for n
the number of lists. You could pimp it a bit to validate lists (or do that upon input). This also preserves the original ordering of the list (assuming members
in the above code is implemented as a list, not a set).
You can obviously do all of the above as well using SPARQL 1.1.
SPARQL 1.1 property paths additionally allow for binding all elements of a list (in a "non-validating" way) using a single query:
PREFIX ...
SELECT *
WHERE {
?u owl:unionOf ?l .
?l rdf:rest*/rdf:first ?el .
}
This will not preserve ordering from the input list, but you can manually bind adjacent elements by doing like:
PREFIX ...
SELECT *
WHERE {
?u owl:unionOf ?l .
?l rdf:rest* ?sl .
?sl rdf:first ?e1 .
?sl rdf:rest ?sln .
?sln rdf:first ?e2 .
}
This will bind all neighbouring pairs in a list to ?e1
and ?e2
.
Some SPARQL engines will support custom magic predicates or other handy voodoo for accessing lists. For example, with Jena/ARQ you can do:
PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>
SELECT ?m
WHERE {
?x owl:unionOf [ list:member ?el ] .
}
This particular syntax will not preserve ordering from the input list.
And that's about it. If none of these are an option for you, mapping RDF lists (internally) to other syntaxes (like the Ordered List Ontology whose members can be reconstituted and ordered in a single SPARQL 1 query) might be a good solution.