I've been playing around with SPARQL queries against the kind of sample data we've been looking at. The aim bring to come up with a set of queries that we can publish alongside some sample data to show how to process a DR.
This document is, in true maths exam style, an attempt to "show my working." For those who prefer to skip to the proposed answer, see the summary.
The data file used in all these examples is at http://www.fosi.org/projects/powder/multiple_examples.rdf
Let's just check it's working with this.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?DR WHERE { ?DR rdf:type wdr:WDR }
Gives a list of the 6 DRs in the RDF instance thus:
We can find out a lot by running a simple query to find all the predicates and objects for a DR thus:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o WHERE { <http://www.fosi.org/projects/powder/multiple_examples.rdf#DR1> ?p ?o }
Which gives us a lot of information
Count | p | o |
---|---|---|
1 | http://www.w3.org/2007/05/powder#hasScope | blank node r1180000947r18520r1 |
2 | http://purl.org/dc/terms/issued | 2007-05-17 |
3 | http://xmlns.com/foaf/0.1/hasMaker | http://www.example.com/foaf.rdf#me |
4 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#WDR |
5 | http://www.w3.org/2007/05/powder#validUntil | 2008-05-17 |
6 | http://www.w3.org/2007/05/powder#hasDescription | blank node r1180000947r18520r2 |
Incidentally, I've given the full URI of the particular DR as the subject. SPARQL defines a way to get data FROM a named graph in the data so that we could re-write Query 2 as:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o FROM <http://www.fosi.org/projects/powder/multiple_examples.rdf#DR1> WHERE { ?x ?p ?o }
Which looks and feels better - but this is a new feature of SPARQL yet to be implemented in Redland which is what I've been using here (so I can't test it with the tools I have available).
This is a very general query that tells us all the predicates and objects of the DR, so everything we want to know is here.
But - two of our key bits of information are in blank nodes. We can solve this in two ways:
Let's try those out.
This asks for specific information that we're looking for
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?maker ?setProp ?setValue ?dsProp ?dsValue ?issued ?validUntil WHERE { <#DR1> foaf:hasMaker ?maker . <#DR1> wdr:hasScope ?rs . ?rs ?setProp ?setValue . <#DR1> wdr:hasDescription ?ds . ?ds ?dsProp ?dsValue . OPTIONAL {<#DR1> dcterms:issued ?issued} OPTIONAL {<#DR1> wdr:validUntil ?validUntil} }
This does return everything we want to know about the DR - attribution, scope and description, plus issue and valid until dates.
Count | maker | setProp | setValue | dsProp | dsValue | issued | validUntil |
---|---|---|---|---|---|---|---|
1 | http://www.example.com/foaf.rdf#me | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.org | http://example.org#colour | black | 2007-05-17 | 2008-05-17 |
2 | http://www.example.com/foaf.rdf#me | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.org | http://example.org#shape | square | 2007-05-17 | 2008-05-17 |
3 | http://www.example.com/foaf.rdf#me | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet | http://example.org#colour | black | 2007-05-17 | 2008-05-17 |
4 | http://www.example.com/foaf.rdf#me | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet | http://example.org#shape | square | 2007-05-17 | 2008-05-17 |
The drawback of this approach is that it would ignore any additional information that might be included. Also,
someone might define their own vocabulary that they then used owl:sameAs
or similar to say that those 'new' terms
were related to our foaf:hasMaker
etc. That should, I think, still be valid but we'd miss it. This is a weak argument!
The idea of getting everything out of a DR in one query is very appealing.
The alternative is to issue specific queries once we can be sure what we're dealing with.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT DISTINCT ?setProp ?setValue WHERE { <#DR1> wdr:hasScope ?rs . ?rs ?setProp ?setValue }
This tells us all about the Resource Set definition for DR 1 and gives us
Count | setProp | setValue |
---|---|---|
1 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
2 | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.org |
We can run a similar query to get the details of the description
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT DISTINCT ?dsProp ?dsValue WHERE { <#DR1> wdr:hasDescription ?ds . ?ds ?dsProp ?dsValue }
Which gives us
Count | dsProp | dsValue |
---|---|---|
1 | http://example.org#colour | black |
2 | http://example.org#shape | square |
So far then, Query 1 tells us that our source file has 6 DRs in it. From a processing point of view, we'd want to know this to be sure we were indeed looking at some POWDER data.
We can then either use Query 3 to take a strict approach to getting everything we need in one go from a particular DR, or we can be a bit more forgiving/flexible and use queries 2, 4 and 5 to get this data. So far then. I 'd say, Query 3 is looking good!
Let's try Query 3 - the strict but get it all in one query - on DR 2.
This is a repeat of query 3 made on <#DR2> rather than <#DR1>
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?maker ?setProp ?setValue ?dsProp ?dsValue ?issued ?validUntil WHERE { <#DR2> foaf:hasMaker ?maker . <#DR2> wdr:hasScope ?rs . ?rs ?setProp ?setValue . <#DR2> wdr:hasDescription ?ds . ?ds ?dsProp ?dsValue . OPTIONAL {<#DR2> dcterms:issued ?issued} OPTIONAL {<#DR2> wdr:validUntil ?validUntil} }
This gives us
We get multiple instances of the data but we can see that everything on example.com or example.org is square and black according to http://www.example.com/foaf.rdf#me on 2007-05-17, an assertion they'll stand by until 2008-05-17.
Notice in DR2 that the description has been removed from the DR (as we've seen in many of our examples to date).
This is looking too easy. In DR 3 the RS definition is separated out and put in a separate block in the same file, whilst the description is moved to a completely different RDF instance. How does Query 3 cope?
Another repeat of query 3, this time against <#DR3>
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?maker ?setProp ?setValue ?dsProp ?dsValue ?issued ?validUntil WHERE { <#DR3> foaf:hasMaker ?maker . <#DR3> wdr:hasScope ?rs . ?rs ?setProp ?setValue . <#DR3> wdr:hasDescription ?ds . ?ds ?dsProp ?dsValue . OPTIONAL {<#DR3> dcterms:issued ?issued} OPTIONAL {<#DR3> wdr:validUntil ?validUntil} }
Which gives a result of
Count | maker | setProp | setValue | dsProp | dsValue | issued | validUntil |
---|
Oops.
Because the description is in a different RDF instance, the SPARQL query can't be completed.
I tried wrapping both the Resource Set and Description in OPTIONAL modifiers as in query 8
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?maker ?rs ?setProp ?setValue ?ds ?dsProp ?dsValue ?issued ?validUntil WHERE { <#DR3> foaf:hasMaker ?maker . <#DR3> wdr:hasScope ?rs. <#DR3> wdr:hasDescription ?ds . OPTIONAL {?rs ?setProp ?setValue} . OPTIONAL {?ds ?dsProp ?dsValue} . OPTIONAL {<#DR3> dcterms:issued ?issued} . OPTIONAL {<#DR3> wdr:validUntil ?validUntil} }
but that didn't work either. This could be a limitation of the Redland RDF kit - I have a feeling it is - but it's probably not going to be the only one that has difficulty with having to fetch bits of RDF from other sources.
Therefore, it seems that the safe way to do this is to work through the DR step by step. Let's go back to query 2 and find out everything we can about this DR.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o WHERE { <#DR3> ?p ?o }
This gives us the following result:
We can see that we have our 3 key properties of foaf:hasMaker
, wdr:hasScope
and wdr:hasDescription
and we have
the URIs of those objects. We also have the issue and valid until dates.
Now we can run specific queries using the data we have as input.
First the scope, which, from line 6 the table above we see is at #RS3.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o WHERE { <#RS3> ?p ?o }
Gives
Count | p | o |
---|---|---|
1 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
2 | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.org example.com |
3 | http://www.w3.org/2007/05/powder#pathStartsWithAnyOf | foo bar |
Which is nice and clear I think.
We can repeat this for the description but will notice that we will be looking at a different RDF instance,
this time http://www.example.com/polygon
(which doesn't exist so there's no point running the query!)
Likewise, if we want to, we could run a query on the object of the foaf:hasMaker property
.
To recap, as things like RS definitions and Descriptions can easily be in locations other than the RDF instance that contains the basic DR, we must run separate queries for those elements.
In the example dataset, DR4 introduces anotherr twist - the use of OWL set operators. How do our queries get on now?
First let's find out what we can with the a simple query (Query 2 modified to refer to DR4)
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o WHERE { <#DR4> ?p ?o }
This gives is the result
Which shows a blank node for wdr:hasScope
. So we need to run a slightly different query now.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?p ?o WHERE { <#DR4> wdr:hasScope ?rs . ?rs ?p ?o }
Which gives us
Count | rs | p | o |
---|---|---|---|
1 | blank node r1180012535r30816r4 | http://www.w3.org/2002/07/owl#unionOf | blank node r1180012535r30816r6 |
2 | blank node r1180012535r30816r4 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
So now we know that our Resource Set uses owl:unionOf
.
Now we know enough to start looking at the Collection
of Resource Sets that are combined using owl:unionOf
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?rs1 ?p ?o WHERE { <#DR4> wdr:hasScope ?rs . ?rs owl:unionOf ?a . ?a rdf:first ?rs1 . ?rs1 ?p ?o }
Which gives
Count | rs | rs1 | p | o |
---|---|---|---|---|
1 | blank node r1180013645r22330r4 | blank node r1180013645r22330r5 | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.org |
2 | blank node r1180013645r22330r4 | blank node r1180013645r22330r5 | http://www.w3.org/2007/05/powder#pathStartsWithAnyOf | foo bar |
3 | blank node r1180013645r22330r4 | blank node r1180013645r22330r5 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
This gives us the data for the first RS in the union. Now we need the next RS which requires another query, but notice that it is similar.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?rs2 ?p ?o WHERE { <#DR4> wdr:hasScope ?rs . ?rs owl:unionOf ?a . ?a rdf:rest ?b . ?b rdf:first ?rs2 ?rs2 ?p ?o }
Which gives
Count | rs | rs2 | p | o |
---|---|---|---|---|
1 | blank node r1180013895r28351r4 | blank node r1180013895r28351r7 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
2 | blank node r1180013895r28351r4 | blank node r1180013895r28351r7 | http://www.w3.org/2007/05/powder#pathStartsWithAnyOf | bar |
3 | blank node r1180013895r28351r4 | blank node r1180013895r28351r7 | http://www.w3.org/2007/05/powder#hasAnyHostFrom | example.net |
We now know the details of the second RS in the union but we don't know whether there is a third so we modify the query again
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?rs3 ?p ?o WHERE { <#DR4> wdr:hasScope ?rs . ?rs owl:unionOf ?a . ?a rdf:rest ?b . ?b rdf:rest ?c ?c rdf:first ?rs3 ?rs3 ?p ?o }
Which gives:
Count | rs | rs3 | p | o |
---|
As this is empty, we know we've reached the end and therefore we have all the data we need to create determine whether or not the candidate resource is or is not in the RS.
So how does all this work with sets derfined by property resource?
DR 5 contains such a Resource Set. Again we'll start with a modified version of Query 2 to get the basic dfata about DR 5
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?p ?o WHERE { <#DR5> ?p ?o }
And we get the result back
As with DR4, we have DR wdr:hasScope
blank node so we need to run Query 12 and see what we get
A modified version of Query 12 to look at the blank node given as scope
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?p ?o WHERE { <#DR5> wdr:hasScope ?rs . ?rs ?p ?o }
Which gives us
Count | rs | p | o |
---|---|---|---|
1 | blank node r1180014404r19324r9 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
2 | blank node r1180014404r19324r9 | http://www.w3.org/2007/05/powder#resourcesWith | blank node r1180014404r19324r10 |
3 | blank node r1180014404r19324r9 | http://www.w3.org/2007/05/powder#hasPropLookUp | blank node r1180014404r19324r11 |
This is quite a different result to the one we got with Query 12. We need to find out what property we're looking for and how to find it.
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?p ?o ?mustHave ?lookUpProp ?lookUpValue WHERE { <#DR5> wdr:hasScope ?rs . ?rs wdr:resourcesWith ?mustHave . ?mustHave ?p ?o. OPTIONAL {?rs wdr:hasPropLookUp ?look} OPTIONAL {?look ?lookUpProp ?lookUpValue} }
Which gives
Count | rs | p | o | mustHave | lookUpProp | lookUpValue |
---|---|---|---|---|---|---|
1 | blank node r1180039697r17448r9 | http://example.org#lang | fr | blank node r1180039697r17448r10 | http://www.w3.org/2007/05/powder#method | http://www.w3.org/2006/http#HeadRequest |
2 | blank node r1180039697r17448r9 | http://example.org#lang | fr | blank node r1180039697r17448r10 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#PropLookUp |
3 | blank node r1180039697r17448r9 | http://example.org#lang | fr | blank node r1180039697r17448r10 | http://www.w3.org/2007/05/powder#responseContains | Content-Language: fr |
4 | blank node r1180039697r17448r9 | http://example.org#lang | fr | blank node r1180039697r17448r10 | http://www.w3.org/2007/05/powder#lookUpURI | $cURI |
In reality, if query 17 revealed that there was a look up method available, you wouldn't need to look at the actual property since there's enough in the look up to tell you all you need to know. But the important point is that queries 17 and 18 extract all the necessary data.
As seems traditional, let's end up with a nasty one - it's not the nastiest imaginable - but it's pretty nasty.
DR 6 has a union of two Resource Sets AND a property definition.
Start with Query 2, modified to look at DR 6
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?p ?o WHERE { <#DR6> ?p ?o }
Which gives
Which starting to look nice and familiar now. We see that wdr:hasScope
has a blank node so we run a modified Query 12
BASE <http://www.fosi.org/projects/powder/multiple_examples.rdf> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX wdr: <http://www.w3.org/2007/05/powder#> PREFIX ex: <http://example.org#> SELECT ?rs ?p ?o WHERE { <#DR6> wdr:hasScope ?rs . ?rs ?p ?o }
Which gives
Count | rs | p | o |
---|---|---|---|
1 | blank node r1180015271r20630r12 | http://www.w3.org/2007/05/powder#hasPropLookUp | blank node r1180015271r20630r18 |
2 | blank node r1180015271r20630r12 | http://www.w3.org/2007/05/powder#resourcesWith | blank node r1180015271r20630r17 |
3 | blank node r1180015271r20630r12 | http://www.w3.org/2002/07/owl#unionOf | blank node r1180015271r20630r14 |
4 | blank node r1180015271r20630r12 | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | http://www.w3.org/2007/05/powder#ResourceSet |
The results here show that we have an owl:unionOf
and a wdr:resourcesWith
predicate. We can follow both of those using
modified versions of queries 13 - 15 and 18.
Query 1 is a good starting point as it tells us whether there are any DRs in the RDF data.
Query 2 gives us the basic predicates and objects of a given DR.
Which query is run next depends on the outcome of Query 2
If the object of wdr:hasScope
is identified by a URI, run a query like Query 10 to find its predicates and objects.
Likewise for wdr:hasDescription
and, if desired, foaf:hasMaker
.
If the object of wdr:hasScope
is a blank node, run Query 12.
If the result of Query 12 shows that the Resource Set contains OWL Set Operators, run a series of queries like those in Query 13 - 15 to find the individual Resource Set Definitions that need to be combined.
If the result of Query 12 shows that the set is defined in terms of resource properties then run Query 18.
Consider DRS without Ids, work more examples and find the pitfalls.
Consider whether there is merit in encoding Resource Sets in XML - i.e. using a different query language for this aspect.