Negation
Sometimes you need to check whether certain
triples don't exist in the RDF graph.
Checking the absence of triples
is a form of negation.
In my specific case I wanted to make a distinction between historical cities which ceased to exist due to a merger or a split and actual cities.
Historical cities have a property 'endDate' while actual haven't; so testing on the existence of a triple having the property 'endDate' allows us to make the distinction.
How does this translate into a SPARQL query?
# Infer actual city, not having an end date.
CONSTRUCT {
?city a :Actual_City .
}
WHERE {
?city a :City .
?city dct:temporal ?period .
OPTIONAL {
?period :enddate ?enddate .
} .
FILTER (!bound(?enddate)) .
}
First collecting cities whether they have 'enddates' or not (OPTIONAL) but then filtering those for which the property 'enddate' has not been bound.
Casting
I want to compare the value of a property 'enddate' being of datatype xsd:date with the day of today.
The Jena ARQ function library (
<
http://jena.hpl.hp.com/ARQ/function#>) offers a function to do this: afn:now().
afn:now() gets the current time as xsd:dateTime: actually, the time the query started.
This results into a comparison of an xsd:date with an xsd:dateTime.
Although this casting is easily achieved in XPath, XSLT, XQuery I did not succeed to do this as easily in SPARQL using the function smf:cast.
I finally came up with following workaround.
?period :endDate ?enddate .
LET (?endDateS := smf:buildString("{?enddate}T00:00:00")) .
LET (?endDateC := smf:cast(?endDateS, xsd:dateTime)) .
FILTER (?endDateC < afn:now()) .
Where I first add to the 'enddate' string, the string for indicating the time.
This string is casted then to an xsd:dateTime.
If anyone has a better solution, please let me know.
Comments