data.ttl:
#base <http://example.org/> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix : <http://example.org/#> .
:Bob a :Student;
:tookTest :Test0,:Test1,:Test2, :Test3, :Test4, :Test5, :Test6, :Test7, :Test8, :Test9.
:Test0 :grade "A" .
:Test1 :grade "A" .
:Test2 :grade "A" .
:Test3 :grade "A" .
:Test4 :grade "A" .
:Test5 :grade "A" .
:Test6 :grade "A" .
:Test7 :grade "B" .
:Test8 :grade "C" .
:Test9 :grade "D" .
sparql query:
PREFIX : <http://example.org/#>
SELECT ?student ?grade (count(?grade) as ?count)
WHERE {
?student :tookTest ?test .
?test :grade ?grade .
}
GROUP BY ?student ?grade
order by ?grade
I get result like follows:
student, grade, count
http://example.org/#Bob,A,7
http://example.org/#Bob,B,1
http://example.org/#Bob,C,1
http://example.org/#Bob,D,1
Now how can I get the same result with Construct?
I used the following query statement, but I didn't get any expected results:
PREFIX : <http://example.org/#>
CONSTRUCT {?student ?grade ?count .}
WHERE {
SELECT ?student ?grade (count(?grade) as ?count)
WHERE {
?student :tookTest ?test .
?test :grade ?grade .
}
GROUP BY ?student ?grade
}
How do I write this Sparql CONSTRUCT statement correctly?
Thanks in advance for help.
I got it done.
replace all "A" with :A , so do with "B", "C", "D".
then everything is OK.
Related
Here is my data.ttl:
#prefix : <http://example.com/ns#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
:Bob a :Student ;
:name "Bob" ;
:tookTest :Test1, :Test2, :Test3, :Test4, :Test5 .
:Test1 a :Test ;
:grade "A" .
:Test2 a :Test ;
:grade "A" .
:Test3 a :Test ;
:grade "A" .
:Test4 a :Test ;
:grade "C" .
:Test5 a :Test ;
:grade "D" .
the shacl.ttl is:
#prefix : <http://example.com/ns#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
:Test a rdfs:Class, sh:NodeShape .
:Student a rdfs:Class, sh:NodeShape ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate :rating ;
sh:object [sh:count [sh:path :Test] ];
] .
and I use shacl inferance engine (https://github.com/TopQuadrant/shacl):
shaclinfer.bat -datafile D:\data.ttl -shapesfile D:\shacl.ttl>D:\report.txt
I get a result report as:
<http://example.com/ns#Bob>
<http://example.com/ns#rating> 0 .
I actually want to implement the following rule:
if Bob get more than 2 "A", then--> :Bob :rating "Outstanding" .
How do I write this sh:condition statement correctly?
In this case sh:count should calculate the number of Test which grade="A",Do I have to use sparql CONSTRUCT statements?
Thanks for any help!
#prefix : <http://example.com/ns#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
:Test a rdfs:Class, sh:NodeShape .
:Student a rdfs:Class, sh:NodeShape ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate :rating ;
sh:object "Outstanding";
sh:condition :Student ;
sh:condition [
sh:qualifiedValueShape [
sh:path (:tookTest :grade ) ;
sh:hasValue "A" ; ] ;
sh:qualifiedMinCount 2 ; ];
] .
The shacl.ttl looks close to correct, but it get error by engine of https://github.com/TopQuadrant/shacl, the error message as follows:
Exception in thread "main" org.apache.jena.query.QueryParseException: Line 2, column 1: Unresolved prefixed name: :tookTest
Would anyone please test this with any of the other SHACL inference engines?
I have the following Data & Shape Graph.
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:prefixes hr: ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path rdf:type ;
sh:nodeKind sh:IRI ;
sh:hasValue rdfs:Class
] ;
.
Using pySHACL:
import rdflib
from pyshacl import validate
full_graph = open( "/Users/jamesh/jigsaw/shacl_work/data_graph.ttl", "r" ).read()
g = rdflib.Graph().parse( data = full_graph, format = 'turtle' )
report = validate( g, inference='rdfs', abort_on_error = False, meta_shacl = False, debug = False )
print( report[2] )
What I think should happen is the SPARQL based target should select every subject in the Data Graph and then verify that there is a path of rdf:type which has a value of rdfs:Class.
I get the following result:
Validation Report
Conforms: True
The expected validation errors should include only the following subjects:
| <http://learningsparql.com/ns/humanResources#BadOne> |
| <http://learningsparql.com/ns/humanResources#BadTwo> |
| <http://learningsparql.com/ns/humanResources#BadThree> |
| <http://learningsparql.com/ns/humanResources#AnotherName> |
| <http://learningsparql.com/ns/humanResources#name> |
| <http://learningsparql.com/ns/humanResources#YetAnotherName> |
Is this possible with SHACL? If so, what should the shape file be?
What follows results in the expected validation errors, however, there are still several things I do not understand.
The sh:prefixes hr: ; is not needed. It is designed to supply prefixes for the SPARQL target SELECT statement itself and nothing more.
Inference needed to be disabled. It was inserting triples and trying to validate them. In this use case, that is not what is desired. What should be validated is what is in the schema and nothing else.
I was also thinking that it would not be an issue to put everything into a single graph based on what apparently was a misunderstanding of https://github.com/RDFLib/pySHACL/issues/46.
graph_data = """
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
"""
shape_data = '''
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:prefixes hr: ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:property [
sh:path ( rdf:type [ sh:zeroOrMorePath rdf:type ] ) ;
sh:nodeKind sh:IRI ;
sh:hasValue rdfs:Class
] ;
.
'''
data = rdflib.Graph().parse( data = graph_data, format = 'turtle' )
shape = rdflib.Graph().parse( data = shape_data, format = 'turtle' )
report = validate( data, shacl_graph=shape, abort_on_error = False, meta_shacl = False, debug = False, advanced = True )
An alternative using a SPARQL based constraint would look like:
graph_data = """
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
hr:Employee a rdfs:Class .
hr:BadThree rdfs:comment "some comment about missing" .
hr:BadTwo a hr:BadOne .
hr:YetAnother a hr:Another .
hr:YetAnotherName a hr:AnotherName .
hr:Another a hr:Employee .
hr:AnotherName a hr:name .
hr:BadOne a hr:Dangling .
hr:name a rdf:Property .
"""
shape_data = '''
#prefix hr: <http://learningsparql.com/ns/humanResources#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix xml: <http://www.w3.org/XML/1998/namespace> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix schema: <http://schema.org/> .
#prefix sh: <http://www.w3.org/ns/shacl#> .
schema:SchemaShape
a sh:NodeShape ;
sh:target [
a sh:SPARQLTarget ;
sh:select """
SELECT ?this
WHERE {
?this ?p ?o .
}
""" ;
] ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "Node does not have type rdfs:Class." ;
sh:prefixes hr: ;
sh:select """
SELECT $this
WHERE {
$this rdf:type ?o .
FILTER NOT EXISTS {
?o rdf:type* rdfs:Class
}
FILTER ( strstarts( str( $this ), str( hr: ) ) )
}
""" ;
]
.
'''
data = rdflib.Graph().parse( data = graph_data, format = 'turtle' )
shape = rdflib.Graph().parse( data = shape_data, format = 'turtle' )
report = validate( data, shacl_graph=shape, abort_on_error = False, meta_shacl = False, debug = False, advanced = True )
I'm new on SPARQL. I read the tutorial on Jena (https://jena.apache.org/tutorials/sparql.html) and I understand most of the example. But I don't really understand when we have to use the a
For example with this triples :
#prefix vCard: <http://www.w3.org/2001/vcard-rdf/3.0#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://somewhere/MattJones/> vCard:FN "Matt Jones" .
<http://somewhere/MattJones/> vCard:N _:b0 .
_:b0 vCard:Family "Jones" .
_:b0 vCard:Given "Matthew" .
<http://somewhere/RebeccaSmith/> vCard:FN "Becky Smith" .
<http://somewhere/RebeccaSmith/> vCard:N _:b1 .
_:b1 vCard:Family "Smith" .
_:b1 vCard:Given "Rebecca" .
<http://somewhere/JohnSmith/> vCard:FN "John Smith" .
<http://somewhere/JohnSmith/> vCard:N _:b2 .
_:b2 vCard:Family "Smith" .
_:b2 vCard:Given "John" .
<http://somewhere/SarahJones/> vCard:FN "Sarah Jones" .
<http://somewhere/SarahJones/> vCard:N _:b3 .
_:b3 vCard:Family "Jones" .
_:b3 vCard:Given "Sarah" .
We can write something like this :
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?y ?givenName
WHERE
{ ?y vcard:Family "Smith" .
?y vcard:Given ?givenName .
}
But I the slideshow of my course I found something like this :
SELECT ?label_du_président ?âge_du_président ? label_du_pays
WHERE {
?une_élection a ex:electionPrésidentielle .
?une_élection ex:gagnéePar ?un_president .
?une_élection ex:alieuDans ?un_pays .
?un_president rdfs:label ?label_du_president .
?un_president ex:âge ?âge_du_president .
?un_pays rdfs:label ?label_du_pays
}
Why and when use the a ?
It's a shorthand notation for the rdf:type property. From the SPARQL Query Language specs:
The keyword "a" can be used as a predicate in a triple pattern and is an alternative for the IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#type. This keyword is case-sensitive.
Think of it as meaning "is a (kind of)".
Trying to use the query in the endpoint. The query was created in SPARQL. The error coming like
Encountered " "<" "< "" at line 1, column 15.
Was expecting:
<IRIref> ...
Query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?Class ?Title ?Definition
WHERE {
?Value rdfs:label ?Class
FILTER regex(?Class, "Motion") .
?def rdfs:domain ?Value .
?def rdfs:label ?Title .
?def rdfs:comment ?Definition}
The url
http://localhost:3030/skosmos/query?query=
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?Class ?Title ?Definition
WHERE {
?Value rdfs:label ?Class
FILTER regex(?Class, "Motion") .
?def rdfs:domain ?Value .
?def rdfs:label ?Title .
?def rdfs:comment ?Definition
}
I took your original query, URL-encoded it with one of many services and tools you might use, randomly selected from a web search, and appended it to the start of what you had as "the URL", http://localhost:3030/skosmos/query?query= ... and you verified that this worked --
http://localhost:3030/skosmos/query?query=PREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0A%0D%0ASELECT+%3FClass+%3FTitle+%3FDefinition%0D%0AWHERE+%7B%0D%0A%3FValue+rdfs%3Alabel+%3FClass%0D%0AFILTER+regex%28%3FClass%2C+%22Motion%22%29+.%0D%0A%3Fdef+rdfs%3Adomain+%3FValue+.%0D%0A%3Fdef+rdfs%3Alabel+%3FTitle+.%0D%0A%3Fdef+rdfs%3Acomment+%3FDefinition%7D
I'm fairly new to RDF / Sparql, so apologies for any incorrect terminology, and also for the fairly terrible example that follows:
Given the following RDF dataset:
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix e: <http://www.example.com/#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
e:Freemason a owl:Class .
e:Civilian a owl:Class .
e:Marty a e:Freemason .
e:Eugene a e:Freemason .
e:Mike a e:Freemason .
e:Alan a e:Freemason .
e:Paul a e:Civilian .
e:Marty foaf:knows e:Eugene .
e:Eugene foaf:knows e:Mike .
e:Eugene foaf:knows e:Paul .
e:Paul foaf:knows e:Alan .
I'm trying to identify friends-of-friends that e:Marty knows through other e:Freemasons only.
So:
Marty knows Mike through Eugene, and they're all Freemason's so it's fine
Marty knows Eugene, who has a Civilian friend Paul. Paul has a Freemason friend Alan. However, Marty doesn't have a "freemason only" path to Alan, so he should be excluded.
Here's the SPARQL query I have:
prefix e: <http://www.example.com/#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
{
<http://www.example.com/#Marty> foaf:knows+ ?target .
?target a e:Freemason .
}
This returns:
http://www.example.com/#Eugene
http://www.example.com/#Mike
http://www.example.com/#Alan
Here, Alan is included as he matches the is-a-freemason criteria.
How I do modify the query to exclude Alan?
I don't know the solution in pure SPARQL, sorry.
In OpenLink Virtuoso's SPARQL-BI, the solution is this query
prefix e: <http://www.example.com/#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
select *
where
{
{ select ?orig ?target
where
{ ?orig foaf:knows ?target .
?target a e:Freemason .
}
}
option ( TRANSITIVE,
T_IN(?orig),
T_OUT(?target),
T_DISTINCT,
T_MIN(1)
)
filter ( ?orig = <http://www.example.com/#Marty> )
}
-- with these results --
orig target
<http://www.example.com/#Marty> <http://www.example.com/#Eugene>
<http://www.example.com/#Marty> <http://www.example.com/#Mike>
Here's an example using SPARQL that has been deprecated from the spec (for reasons I never understood) but remains supported in Virtuoso (which will be the case for the unforeseeable future)
## RDF-Turtle Start ##
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix e: <http://www.example.com/#> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
e:Freemason a owl:Class .
e:Civilian a owl:Class .
e:Marty a e:Freemason .
e:Eugene a e:Freemason .
e:Mike a e:Freemason .
e:Alan a e:Freemason .
e:Paul a e:Civilian .
e:Marty foaf:knows e:Eugene .
e:Eugene foaf:knows e:Mike .
e:Eugene foaf:knows e:Paul .
e:Paul foaf:knows e:Alan .
## RDF-Turtle End ##
Using Property Path Pattern from SPARQL that has been deprecated
but preserved in Virtuoso
PREFIX e: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.ttl#>
PREFIX dsn: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
FROM dsn:ttl
WHERE {
e:Marty foaf:knows{2} ?target .
?target a e:Freemason .
}
Live Links:
Query Solution
Query Definition