Re: Processing RDF in XML/XSLT workflows

On Tue, Apr 27, 2010 at 9:21 AM, James Leigh <james-nospam@leighnet.ca> wrote:
> On Mon, 2010-04-26 at 17:14 -0400, Bob DuCharme wrote:
>> Hi Johan,
>>
>>  >SPARQL result xml is not a full solution because it is limited to ASK
>> and SELECT queries.
>>
>> Can you give me some examples of a need to process RDF with XSLT where
>> the results of a SELECT query were inappropriate?
>>
>> thanks,
>>
>> Bob
>>
>>
>
> Any CONSTRUCT template that dose not represent the actually triples in
> the RDF store cannot be represented in a SPARQL 1.0 SELECT.

What you're pointing out here is that SPARQL SELECT cannot be used to
bind a variable to a particular value that doesn't necessarily appear
in the graph. Unlike SQL where you can say something like:
  SELECT x, y, "foo" as "foo" FROM......

Of course, some SPARQL implementations do have an extension that
allows for this like of thing (such as LET expressions), but it's not
standard.

I don't think this should be a problem, as it is still possible to
select all the data you need. Of course, you can't differentiate
bindings of your results by the predicates you want to create, but
there are alternatives. For instance, you can UNION sets of results,
and the bound variables will indicate the data you are interested in.
Let's take your example:

> Here is a simplified example of a query that uses SPARQL CONSTRUCT. It
> is similar to more complex queries we use with rdf+xml and XSLT. I will
> also note here that the XSLT we use is filled with complicated
> application logic. Any suggestions to move the domain reasoning to XSLT
> would be unrealistic.
>
> CONSTRUCT { ?s :friend ?friend; :acquaintance ?acquaintance }
> WHERE { ?s foaf:knows ?friend; foaf:knows ?acquaintance .
> ?friend foaf:knows ?s
> OPTIONAL { ?acquaintance ?knows ?s FILTER (?knows = foaf:knows)}
> FILTER (!bound(?knows))
> }


The same data can be represented (albeit in a different structure) with:

SELECT ?s ?friend ?acquaintance
WHERE {
  { ?s foaf:knows ?friend . ?friend foaf:knows ?s }
  UNION
  { ?s foaf:knows ?acquaintance
    OPTIONAL { ?acquaintance ?knows ?s FILTER (?knows = foaf:knows) }
    FILTER (!bound(?knows)) }
}

This will return bindings of (?s, ?friend) for friends, and bindings
of (?s, ?acquaintance) for acquaintances. No binding will include all
three variables.

Now, I'm not saying that this is easy to process in XSLT, but you
*can* process this in XSLT.

> I would also be interested to see if this query could be represented in
> SPARQL 1.1 SELECT.

I think so, yes.

In your CONSTRUCT operation you are converting each binding into a
pair of rows in the output (well, it's potentially a pair). To get
that effect you'd still need a UNION.

SPARQL 1.1 also lets you project expressions into your SELECT clause,
but this would be tricky to only return when a particular variable is
bound (e.g. you only want the :acquaintance predicate when your
?acquaintance variable is bound). I'm pretty sure you can do this with
a subquery.

Finally, you can also use a new MINUS syntax to avoid the
OPTIONAL/!bound construct.

SELECT ?s ?pred_fr ?friend ?pred_ac ?acquaintance
WHERE {
  {
    SELECT ?s (:friend AS ?pred_fr) ?friend
    WHERE { ?s foaf:knows ?friend }
  }
  UNION
  {
    SELECT ?s (:acquaintance AS ?pred_ac) ?acquaintance
    WHERE {
      ?s foaf:knows ?acquaintance
      MINUS ?acquaintance :knows ?s
    }
  }
}

Looking at it, the CONSTRUCT might be easier, huh?  :-)

Regards,
Paul

Received on Tuesday, 27 April 2010 17:41:28 UTC