Lqraps is backwards SPARQL. W3C's SPARQL lets you get a table of variable/value bindings by asking questions of a collection of RDF graphs. Lqraps does the reverse: by annotating a tabular resultset, and rebinding the results to fragments of RDF (specified using SPARQL's CONSTRUCT notation) you can generate RDF.
Status: Rough cut only. Sketch of what we could do here.
The original idea here stems from an observation of R.V.Guha's, in the QL'1998 paper, "Enabling Inference". Discussing a simple RDF query proposal:
The query is itself simply an RDF model (i.e., a directed labelled graph), some of whose resources and properties may represent variables. There are two outputs to every query, 1. A subgraph (of the KB against which the query is issued) which matches the query. 2. A table of sets of legal bindings for the variables, i.e., when these bindings are applied to the variables in the query, we get (1).
In the years following, W3C has standardised the SPARQL query language for RDF. It differs from the original Guha et al. proposal in several ways. In addition to the GRAPH keyword, which doesn't impact upon Lqraps' design, SPARQL queries can contain optionals, filters, and can use DESCRIBE and ASK query forms. As such, a raw unconstrained SPARQL query can have various features that make it ill-suited to data-reconstruction by variable rebinding. However SPARQL also provides for the CONSTRUCT query form, which is explicitly designed for generating RDF from a set of bindings.
#!/usr/bin/env lqraps
# PREFIX : <http://xmlns.com/foaf/0.1/>
# PREFIX u: <http://kota.s12.xrea.com/vocab/uranai>
# CONSTRUCT { [ a :Person; :name ?n; :homepage ?hp; u:bloodtype ?bt ] }
# LQRAPS ?n ?hp ?bt
#
Dan Brickley http://danbri.org/ A+
John Doe http://spares.example.com/ A+
Alice Exemplar http://example.org/alice/ O
Libby Miller http://nicecupoftea.org/ A
./people.lq > test.n3
rapper -i turtle test.n3
[pocky]$ roqet -s test.n3 blood.rq
roqet: Querying from file blood.rq
roqet: Query has a variable bindings result
result: [url=uri<http://example.org/alice/>, name=string("Alice
Exemplar")]
roqet: Query returned 1 results
See files. Can you tell what they do? :)
The toy Ruby implementation here expects a tab separate file only. Clearly we should extend this to allow comma separated, quote delimited etc., and find common ground across the various existing CSV/tab-etc parsers.
RDF (and hence SPARQL) makes some distinctions that are rarely explicit in tabular data. Language tagging of literals, datatyping, and most critically the distinction between literal and non-literal resources. This last distinction is the most urgent to handle well; here, I handle it badly. Unless a value begins 'http:/', it becomes a plain literal with no language tag. The desire here is to allow reasonable RDF expressivity while still keeping the inline annotations pretty simple. For a more full-featured approach, see the tools and languages around SQL/RDF mappings (D2RQ, SquirrelRDF, Virtuoso etc).
See also discussion from SWIG IRC ...
Embedding an Lqraps-style CONSTRUCT in SPARQL result set formats (JSON, XML) is left as an exercise for readers... See also discussion with ndw.
Dan Brickley, Feb 2008. Dec 2009.