Reputation: 612
rdf:Seq
is a sequence of RDF properties rdf:_1
, rdf:_2
, rdf:_3
...
Can it be validated using a SPARQL 1.1 query? For example, if the sequence is valid, an ASK
query should return true
, otherwise false
.
The constraints that I can think of right now:
rdf:_1
rdf:_2
, rdf:_2
)rdf:_2
, rdf:_4
)I suspect a completely generic solution can be difficult due to the absence of recursion in SPARQL. But a pragmatic solution that validates a finite number of members (say 30 or 50) would be acceptable as well.
Upvotes: 1
Views: 242
Reputation: 1519
One could just check, if there is some item with another item of the same position or if there is an item without direct predecessor. Unfortunately, this requires some ugly and expensive string operations, so this will probably take longer on large datasets. This query ignores that the duplicate might actually be the same (owl:sameAs
).
Sample Data:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
@prefix ex: <http://example.org/>
ex:a a rdf:Seq;
rdf:_1 ex:a1 ;
rdf:_2 ex:a2 .
ex:b a rdf:Bag;
rdf:_1 ex:b1 ;
rdf:_1 ex:b2 .
ex:c a rdf:Alt;
rdf:_2 ex:c1 .
ex:d a rdf:Seq;
rdf:_0 ex:d1 ;
rdf:_1 ex:d2 .
Query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?container ?containerMembershipProperty ?item ?error WHERE {
{
?container a rdf:Seq .
} UNION {
?container a rdf:Bag .
} UNION {
?container a rdf:Alt .
}
{
BIND("Duplicated Index" AS ?error)
?container ?containerMembershipProperty ?item .
FILTER strstarts(str(?containerMembershipProperty),"http://www.w3.org/1999/02/22-rdf-syntax-ns#_")
FILTER EXISTS {
?container ?containerMembershipProperty ?item2 .
FILTER (?item!=?item2)
}
} UNION {
BIND("Missing Predecessor" AS ?error)
?container ?containerMembershipProperty ?item .
BIND(xsd:integer(STRAFTER(STR(?containerMembershipProperty),"http://www.w3.org/1999/02/22-rdf-syntax-ns#_")) - 1 AS ?index)
BIND(IRI(CONCAT("http://www.w3.org/1999/02/22-rdf-syntax-ns#_", STR(?index))) AS ?previousContainerMembershipProperty)
FILTER (?index >= 1)
FILTER NOT EXISTS {
?container ?previousContainerMembershipProperty ?item3
}
} UNION {
BIND("Illegal Index" AS ?error)
?container ?containerMembershipProperty ?item .
BIND(xsd:integer(STRAFTER(STR(?containerMembershipProperty),"http://www.w3.org/1999/02/22-rdf-syntax-ns#_")) AS ?index)
FILTER (?index < 1)
}
}
ORDER BY ?container ?containerMembershipProperty ?item
Result:
container | containerMembershipProperty | item | error |
---|---|---|---|
http://example.org/b | rdf:_1 | http://example.org/b1 | "Duplicated Index" |
http://example.org/b | rdf:_1 | http://example.org/b2 | "Duplicated Index" |
http://example.org/c | rdf:_2 | http://example.org/c1 | "Missing Predecessor" |
http://example.org/d | rdf:_0 | http://example.org/d1 | "Illegal Index" |
Upvotes: 3