I can upload the following turtle file to a Virtuoso SPARQL endpoint without an getting an error or a warning:
@base <> .
@prefix :<>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
# wrong
:x :y "kind of?"^^xsd:boolean.
:x :y "whenever"^^xsd:date.
:x :y "2000-01-01"^^xsd:dateTime.
:x :y "2000-01-01-06:00"^^xsd:date.
:x :y "01012000"^^xsd:date.
:x :y "x"^^xsd:integer.
:x :y "-1"^^xsd:nonNegativeInteger.
:x :y "0"^^xsd:positiveInteger.
# correct
:x :y "2000-01-01"^^xsd:date.
:x :y "2000-01-01-06:00"^^xsd:dateTime.
:x :y "true"^^xsd:boolean.
:x :y "false"^^xsd:boolean.
:x :y "-5"^^xsd:integer.
:x :y "0"^^xsd:nonNegativeInteger.
:x :y "1"^^xsd:positiveInteger.
The integer value gets converted to a "0" on upload but the date and the integer subtypes are uploaded as given.
Is there a predefined procedure or another standardized way to check if my literals conform to their data types in a SPARQL query?
This is what I came up with for xsd:date
, xsd:dateTime
, xsd:boolean
, xsd:integer
and subtypes:
select *
{
?s ?p ?o.
filter(!isIRI(?o)).
bind(datatype(?o) as ?type)
filter
(
(?type=xsd:boolean&&xsd:boolean(?o)!=?o)
|| (?type=xsd:date&&xsd:date(?o)!=?o)
|| (?type=xsd:integer&&xsd:int(?o)!=?o)
|| ((?type=xsd:positiveInteger) && (xsd:int(?o)!=?o||xsd:int(?o)<1))
|| ((?type=xsd:nonNegativeInteger) && (xsd:int(?o)!=?o||xsd:int(?o)<0))
)
}
However it doesn't show a warning for those dateTimes without time and dates with time:
:x :y "2000-01-01"^^xsd:dateTime.
:x :y "2000-01-01-06:00"^^xsd:date.
How errors and warnings are handled is a feature of the tools used. As noted in the comments, "kind of?"^^xsd:boolean
is a legal literal; it is illegal in conformance with the datatype. An RDF parser may not know about the dataype.
The app can validate data before sending it. Otherwise, warning are likely in the server logs.
An on-line service for parsing data (don't use for anything big!) is
http://www.sparql.org/data-validator.html
which is based on Apache Jena.
The warnings are (in addition to the ones due to a prefix with relative URI <>
):
[line: 6, col: 7 ] Lexical form 'kind of?' not valid for datatype XSD boolean
[line: 8, col: 7 ] Lexical form 'whenever' not valid for datatype XSD date
[line: 9, col: 7 ] Lexical form '2000-01-01' not valid for datatype XSD dateTime
[line: 12, col: 7 ] Lexical form '01012000' not valid for datatype XSD date
[line: 14, col: 7 ] Lexical form 'x' not valid for datatype XSD integer
[line: 15, col: 7 ] Lexical form '-1' not valid for datatype XSD nonNegativeInteger
[line: 16, col: 7 ] Lexical form '0' not valid for datatype XSD positiveInteger
[line: 21, col: 7 ] Lexical form '2000-01-01-06:00' not valid for datatype XSD dateTime
The SPARQL test
xsd:dateTime(str(?o)) = ?o
and so on for the other datatypes (note the extra "str") is a good idea.