On 16 Aug 2009, at 21:54, melvincarvalho wrote:
> I'm working on a little project to provide read/write ability to an
> (arbitrary) RDFa page using RDFQuery and SPARQL Update (SPARUL).
>
> I was wondering if you might have any insights on, a good way of going
> about it.
> [snip]
> 3. I then use RDFQuery to work out what the triples were before, and
> what the triples are after, and generate the appropriate SPARUL
> [snip]
> I have most of (1)-(6) in place, but was curious as whether there's a
> good way of achieving (3) it to go from RDFa to SPARUL using
> RDFQuery.
You can do this by:
1. creating a rdfQuery object containing the triples before any
editing takes place, using something like:
var before = $('html').rdf().databank;
2. creating another rdfQuery object containing the triples after the
edits are done, using something like:
var after = $('html').rdf().databank;
3. creating the SPARUL using normal Javascript string manipulation.
You can find out which triples have been removed and added using the
$.rdf.databank.except() method, and you can use the fact that the
string value of a triple uses the same representation as is expected
in SPARQL. So I think you can just do something like:
var sparul = 'DELETE DATA { ';
before
.except(after)
.triples()
.each(function () {
sparul += this + ' ';
})
sparul += '} INSERT DATA { ';
after
.except(before)
.triples()
.each(function () {
sparul += this + ' ';
})
sparul += '}';
Let us know whether that works for you, and whether there's anything
that you think rdfQuery could do to make what you're doing easier.
Cheers,
Jeni
--
Jeni Tennison
http://www.jenitennison.com
I don't know if it would help you any, but the
$.rdf.databank.describe() method creates a simple concise bounded
description [1] of whatever subject you pass to it. So you could, I
think, do something like:
removed = stored.except(revised);
removed
.where('?s ?p ?o')
.each(function () {
stored
.describe(this.s)
.each(function () {
removed.add(this);
});
})
This would be speeded up if you didn't iterate over all the triples --
if you only iterated once per subject. You can do that with the new
group() method which is in the trunk version of the code but not
currently released. I think this might work:
removed = stored.except(revised);
removed
.where('?s ?p ?o')
.group('s')
.each(function () {
stored
.describe(this.s)
.each(function () {
removed.add(this);
});
})
but it might not; looks like group() returns an array rather than a
jQuery object, which makes things rather less elegant. I'll change that.
In general you will be better off using the rdfQuery methods for
locating items within a databank than iterating over the databank
triples. rdfQuery uses indexes on the databank and a Rete algorithm to
help speed up searches over the databank (though you won't benefit
from the latter when you're only doing a couple of searches).
For example, instead of:
> var bnode = triple.object
> store.triples().each(function(){
> if (this.subject.value == bnode.value) {
> addBoundedDescription(this, store, description)
> }
> })
you should do something like:
var bnode = triple.subject;
$.rdf({databank: store})
.where(bnode + ' ?p ?o')
.each(function (i, bindings, triples) {
addBoundedDescription(triples[0], store, description);
});
All code untested and written whilst mildly intoxicated. Good luck!
Let us know how you get on, and if anything can be made simpler for you.
Cheers,
Jeni
[1]: http://n2.talis.com/wiki/Bounded_Descriptions_in_RDF#Simple_Concise_Bounded_Description
It's doing the filtering itself. It looks like you're not using the
trunk version of rdfQuery; there, I've updated findMatches to use the
indexes within the databank much better, so you might find a
performance improvement if you move to trunk.
If you're calling getObjects repeatedly, iterating over different
predicates on the same subject, you *might* find it more efficient to
use two steps like:
return $.rdf({ databank: store })
.about(subj)
.where(subj + ' <' + pred + '> ?obj')
.map(function () { return this.obj; });
Cheers,
Jeni