Display Individual with multiple properties using sparql - sparql

I have individual that contain properties has_answer and has_choice two time.
<!-- http://www.semanticweb.org/myontology#Which_of_the_following_planet_has_the_average_speed_of_about_30Km/Seconds -->
<owl:NamedIndividual rdf:about="&myontology;Which_of_the_following_planet_has_the_average_speed_of_about_30Km/Seconds">
<rdf:type rdf:resource="&myontology;Question"/>
<rdfs:label>Which of the following planet has the average speed of about 30Km/Seconds ?</rdfs:label>
<myontology:QuestionNumber>1</myontology:QuestionNumber>
<myontology:has_answer rdf:resource="http://dbpedia.org/resource/Earth"/>
<myontology:has_choice rdf:resource="http://dbpedia.org/resource/Mars"/>
<myontology:has_choice rdf:resource="http://dbpedia.org/resource/Moon"/>
<myontology:has_score rdf:resource="&myontology;4_points"/>
<myontology:has_Level rdf:resource="&myontology;Expert"/>
</owl:NamedIndividual>
What I want to do is to get the property list from the Individual
+ "SELECT distinct ?Qs ?CorrAns ?Choice "
+ "WHERE {?Question rdf:type owl:NamedIndividual."
+ "?Question rdfs:label ?Qs. "
+ "?Question myontology:has_answer ?CorrAns."
+ "?Question myontology:has_choice ?Choice."
//
+ "}"
// + "GROUP BY ?Qs"
+ "";
...
while (rs.hasNext()) {
QuerySolution soln = rs.nextSolution();
String Qs = soln.getLiteral("Qs").getString();
RDFNode choice = soln.get("Choice");
String ans = choice.asNode().getLocalName();
RDFNode Canswer = soln.get("CorrAns");
String cans = Canswer.asNode().getLocalName();
....
that give me result as following :
Which of the following planet has the average speed of about 30Km/Seconds ? Choice : Mars CorrectAns: Earth
Which of the following planet has the average speed of about 30Km/Seconds ? Choice : Moon CorrectAns: Earth
my question is how can I do to get result in one line as following :
Which of the following planet has the average speed of about 30Km/Seconds ? || choice 1 : Mars || choice 2 : Moon || CorrecAns : Earth
is it possible with Sparql to do that ?

I solve my question by following #AKSW answers, and fix some issue in my OWL file

Related

Access subclassOf/subclassOf level using ForwardChainingRDFSInferencer with SPARQL

I am running some SPARQL queries using the class ForwardChainingRDFSInferencer, which basic constructs an inferencer. For my examples I use the schema.org ontology.
My code looks like the following example
MemoryStore store = new MemoryStore();
ForwardChainingRDFSInferencer inferencer = new ForwardChainingRDFSInferencer(store); //the inference class
Repository repo = new SailRepository(inferencer);
repo.initialize();
URL data = new URL("file:/home/user/Documents/schemaorg-current-https.nt");
RDFFormat fileRDFFormat = RDFFormat.NTRIPLES;
RepositoryConnection con = repo.getConnection();
con.add(data, null, fileRDFFormat);
System.out.println("Repository loaded");
String queryString =
" PREFIX schema: <https://schema.org/>" +
" SELECT DISTINCT ?subclassName_one" +
" WHERE { " +
" ?type rdf:type rdfs:Class ." +
" ?type rdfs:subClassOf/rdfs:subClassOf? schema:Thing ." +
" ?type rdfs:label ?subclassName_one ." +
" }";
TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
TupleQueryResult result = tupleQuery.evaluate();
while (result.hasNext()) {
BindingSet bindingSet = result.next();
System.out.println(bindingSet.toString());
stdout.println(bindingSet.toString());
}
repo.close()
What I want is to print two subclass levels down the class Thing. So if for example we have,
Thing > Action (sub-class 1) > ConsumeAction (sub-class 2) > DrinkAction
What I want is to return the class CosumeAction which is two levels (subclasses) down from class Thing, while using the inference java class.
The current query, as given in the code sample above, returns all the classes and subclasses from every class of the schema.org ontology. Thus, there is something that I do wrong while using the inference class.
You could remove the classes you are not interested in with FILTER NOT EXISTS:
FILTER NOT EXISTS {
?type rdfs:subClassOf+/rdfs:subClassOf/rdfs:subClassOf schema:Thing .
}
Examples
For DrinkAction (level 3):
FILTER NOT EXISTS {
?type
rdfs:subClassOf+ / # schema:ConsumeAction
rdfs:subClassOf / # schema:Action
rdfs:subClassOf schema:Thing .
}
For WearAction (level 4):
FILTER NOT EXISTS {
?type
rdfs:subClassOf+ / # schema:UseAction / schema:ConsumeAction
rdfs:subClassOf / # schema:Action
rdfs:subClassOf schema:Thing .
}

How to convert a class expression (from restriction unionOf) to a string?

A SPARQL query returns a result with restrictions with allValuesFrom and unionOf. I need do concat these values, but, when I use bind or str functions, the result is blank.
I tried bind, str and group_concat functions, but, all of it was unsuccessful. Group_concat return a blank node.
SELECT DISTINCT ?source ?is_succeeded_by
WHERE {
?source rdfs:subClassOf ?restriction .
?restriction owl:onProperty j.0:isSucceededBy .
?restriction owl:allValuesFrom ?is_succeeded_by .
FILTER (REGEX(STR(?source), 'gatw-Invoice_match'))
}
Result of SPARQL query in Protegé:
You can hardly obtain strings like 'xxx or yyy' programmatically in Jena,
since it is Manchester Syntax, an OWL-API native format, and it is not supported by Jena.
Any class expression is actually b-node, there are no such builtin symbols like 'or' in raw RDF.
To represent any anonymous class expression as a string, you can use ONT-API,
which is a jena-based OWL-API, and, therefore, both SPARQL and Manchester Syntax are supported there.
Here is an example based on pizza ontology:
// use pizza, since no example data provided in the question:
IRI pizza = IRI.create("https://raw.githubusercontent.com/owlcs/ont-api/master/src/test/resources/ontapi/pizza.ttl");
// get OWLOntologyManager instance from ONT-API
OntologyManager manager = OntManagers.createONT();
// as extended Jena model:
OntModel model = manager.loadOntology(pizza).asGraphModel();
// prepare query that looks like the original, but for pizza
String txt = "SELECT DISTINCT ?source ?is_succeeded_by\n" +
"WHERE {\n" +
" ?source rdfs:subClassOf ?restriction . \n" +
" ?restriction owl:onProperty :hasTopping . \n" +
" ?restriction owl:allValuesFrom ?is_succeeded_by .\n" +
" FILTER (REGEX(STR(?source), 'Am'))\n" +
"}";
Query q = new Query();
q.setPrefixMapping(model);
q = QueryFactory.parse(q, txt, null, Syntax.defaultQuerySyntax);
// from owlapi-parsers package:
OWLObjectRenderer renderer = new ManchesterOWLSyntaxOWLObjectRendererImpl();
// from ont-api (although it is a part of internal API, it is public):
InternalObjectFactory iof = new SimpleObjectFactory(manager.getOWLDataFactory());
// exec SPARQL query:
try (QueryExecution exec = QueryExecutionFactory.create(q, model)) {
ResultSet res = exec.execSelect();
while (res.hasNext()) {
QuerySolution qs = res.next();
List<Resource> vars = Iter.asStream(qs.varNames()).map(qs::getResource).collect(Collectors.toList());
if (vars.size() != 2)
throw new IllegalStateException("For the specified query and valid OWL must not happen");
// Resource (Jena) -> OntCE (ONT-API) -> ONTObject (ONT-API) -> OWLClassExpression (OWL-API)
OWLClassExpression ex = iof.getClass(vars.get(1).inModel(model).as(OntClass.class)).getOWLObject();
// format: 'class local name' ||| 'superclass string in ManSyn'
System.out.println(vars.get(0).getLocalName() + " ||| " + renderer.render(ex));
}
}
The output:
American ||| MozzarellaTopping or PeperoniSausageTopping or TomatoTopping
AmericanHot ||| HotGreenPepperTopping or JalapenoPepperTopping or MozzarellaTopping or PeperoniSausageTopping or TomatoTopping
Used env: ont-api:2.0.0, owl-api:5.1.11, jena-arq:3.13.1

How do i extract the fragment value, the bit after #, in a SPARQL query

I wrote the following jena query in Eclipse which produces a URI and description of a medical disorder pertaining to the inner ear.
public static void main(String[] args) {
String FOAF = "http://http://xmlns.com/foaf/0.1/";
String NS = "http://philshields.altervista.org/owl/_";
String rdf= "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
String owl= "http://www.w3.org/2002/07/owl#" ;
String xsd= "http://www.w3.org/2001/XMLSchema#";
String rdfs= "http://www.w3.org/2000/01/rdf-schema#";
String dc= "http://purl.org/dc/elements/1.1/";
Model model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM );
//model = FileManager.get().loadModel("c:/Ontologies/ICD-10 ontologies/2017_10_26_ICD10_AM_Code Order.owl");
model = FileManager.get().loadModel("c:/jena/ICD.owl");
String resultsAsString;
String queryString = "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\r\n" +
"PREFIX owl: <http://www.w3.org/2002/07/owl#>\r\n" +
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\r\n" +
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\r\n" +
"PREFIX dc: <http://purl.org/dc/elements/1.1/>\r\n" +
"SELECT (str(?subject) AS ?string) ?object\r\n" +
" WHERE {?subject dc:title ?object \r\n" +
"FILTER regex(?object,\"inner ear\",\"i\")}\r\n" +
"" ;
Query query = QueryFactory.create(queryString) ;
try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {
ResultSet results = qexec.execSelect() ;
for ( ; results.hasNext() ; )
{
//QuerySolution soln = results.nextSolution() ;
ResultSetFormatter.out(System.out, results, query) ;
}
}
}
It produces the correct results shown here:
-------------------------------------------------------------------------------------------------------------------------------------
| string | object |
=====================================================================================================================================
| "http://www.semanticweb.org/philshields/ontologies/2017/8/untitled-ontology-341#H83.3" | "Noise effects on inner ear" |
| "http://www.semanticweb.org/philshields/ontologies/2017/8/untitled-ontology-341#S01.38" | "Open wound of inner ear" |
| "http://www.semanticweb.org/philshields/ontologies/2017/8/untitled-ontology-341#H83.8" | "Other specified diseases of inner ear" |
| "http://www.semanticweb.org/philshields/ontologies/2017/8/untitled-ontology-341#H83.9" | "Disease of inner ear, unspecified" |
I am trying to discard all of the URI and keep the fragment value which is the code number of the disorder after the hash.
I tried using SELECT (str(?subject) AS ?string) ?object, but it does not work.
SPARQL way:
SELECT (strafter(str(?subject), "#") as ?fragment) WHERE
{
#... Something...
}
JAVA way:
Resource subject = // Some way to fetch from your query;
String fragment = resource.getlocalName(); // This will return fragment

SPARQL delete query dotNetRDF does not modify RDF file

I like to delete a RDF tuple from a RDF file using dotNetRDF. Here is the code I'm using
public void deleteDest(string destID)
{
TripleStore store = new TripleStore();
Graph rdf = new Graph();
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
store.Add(rdf);
SparqlUpdateParser parser = new SparqlUpdateParser();
SparqlParameterizedString cmdString = new SparqlParameterizedString();
cmdString.CommandText = "PREFIX j.0: <http://www.example.org/destDetails#>"
+ "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"
+ "DELETE "
+ "WHERE { "
+ " ?dest j.0:ID \"" + destID + "\" "
+ "}";
SparqlUpdateCommandSet cmds = parser.ParseFromString(cmdString);
LeviathanUpdateProcessor processor = new LeviathanUpdateProcessor(store);
processor.ProcessCommandSet(cmds);
rdf.SaveToFile(rdfFilePath);
}
Here is the structure of my RDF file
<rdf:RDF xml:base="http://www.example.org/destDetails#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:ns0="http://www.example.org/destDetails#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="&ns0;0165a659-54ea-4e80-bee7-9d3951d47ae3">
<ns0:ID>0165a659-54ea-4e80-bee7-9d3951d47ae3</ns0:ID>
<ns0:destination rdf:resource="&ns0;VELES" />
<ns0:distrName>Test Test</ns0:distrName>
<ns0:hasTimeStart>17:00</ns0:hasTimeStart>
<ns0:hasTimeStop>17:55</ns0:hasTimeStop>
<ns0:moneyOneDir>130 den.</ns0:moneyOneDir>
<ns0:moneyTwoDir>---</ns0:moneyTwoDir>
</rdf:Description>
</rdf:RDF>
However, no changes are applied to the RDF file.
The problem is that your update operates over the default graph but that your dataset only contains a named graph.
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
store.Add(rdf);
When you do the above this loads data into your graph and assigns that graph a name based on the source of the data - in your case it gets a file:// URI. Then when you add it to the store the store uses the current name of the graph (from the BaseUri property of the graph) and adds it as a named graph.
However your DELETE only references the default graph which is empty in your example and your named graph is not modified in any way. There are several different ways to fix this problem.
1 - Construct your dataset explicitly
You can specify that your named graph be treated as the default graph like so:
// Create a dataset and use the named graph as the default graph
InMemoryDataset ds = new InMemoryDataset(store, rdf.BaseUri);
// Use the dataset to create the processor
LeviathanUpdateProcessor processor = new LeviathanUpdateProcessor(ds);
2 - Add your named graph as the default graph
You can make your named graph be treated as the default graph by removing its name before you add it to the store:
FileLoader.Load(rdf, rdfFilePath, new RdfXmlParser());
rdf.BaseUri = null; // Remove the name from the graph
// If the graph has no name it is added as the default graph
store.Add(rdf);
3 - Rewrite your update
You can rewrite your DELETE to reference the named graph explicitly:
cmdString.CommandText = #"PREFIX j.0: <http://www.example.org/destDetails#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
DELETE WHERE
{
GRAPH #graph { ?dest j.0:ID #destID }
}";
cmdString.SetUri("graph", rdf.BaseUri);
cmdString.SetLiteral("destID", destID);
Note that I've used verbatim string literals for readability and injected the parameters via SetUri() and SetLiteral() rather than string concatenation.
There is an extra space \"" + destID + "\" " (marked with an X --> \"" + destID + "\"X")

Sparql Query With Inferencing

i have some rdf & rdfs files and i want to use jena sparql implementation to query it and my code look like :
//model of my rdf file
Model model = ModelFactory.createMemModelMaker().createDefaultModel();
model.read(inputStream1, null);
//model of my ontology (word net) file
Model onto = ModelFactory.createOntologyModel( OntModelSpec.RDFS_MEM_RDFS_INF);
onto.read( inputStream2,null);
String queryString =
"PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
+ "PREFIX wn:<http://www.webkb.org/theKB_terms.rdf/wn#> "
+ "SELECT ?person "
+ "WHERE {"
+ " ?person rdf:type wn:Person . "
+ " }";
Query query = QueryFactory.create(queryString);
QueryExecution qe = QueryExecutionFactory.create(query, ????);
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results, query);
qe.close();
and i have a wordNet Ontology in rdf file and i want to use this ontology in my query to do Inferencing automaticly (when i query for person the query should return eg. Man ,Woman)
so how to link the ontology to my query? please help me.
update: now i have tow models : from which i should run my query ?
QueryExecution qe = QueryExecutionFactory.create(query, ????);
thanks in advance.
The key is to recognise that, in Jena, Model is the one of the central abstractions. An inferencing model is just a Model, in which some of the triples are present because they are entailed by inference rules rather than read in from the source document. Thus you only need to change the first line of your example, where you create the model initially.
While you can create inference models directly, it's often easiest just to create an OntModel with the required degree of inference support:
Model model = ModelFactory.createOntologyModel( OntModelSpec.RDFS_MEM_RDFS_INF );
If you want a different reasoner, or OWL support, you can select a different OntModelSpec constant. Be aware that large and/or complex models can make for slow queries.
Update (following edit of original question)
To reason over two models, you want the union. You can do this through OntModel's sub-model factility. I would change your example as follows (note: I haven't tested this code, but it should work):
String rdfFile = "... your RDF file location ...";
Model source = FileManager.get().loadModel( rdfFile );
String ontFile = "... your ontology file location ...";
Model ont = FileManager.get().loadModel( ontFile );
Model m = ModelFactory.createOntologyModel( OntModelSpec.RDFS_MEM_RDFS_INF, ont );
m.addSubModel( source );
String queryString =
"PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
+ "PREFIX wn:<http://www.webkb.org/theKB_terms.rdf/wn#> "
+ "SELECT ?person "
+ "WHERE {"
+ " ?person rdf:type wn:Person . "
+ " }";
Query query = QueryFactory.create(queryString);
QueryExecution qe = QueryExecutionFactory.create(query, m);
ResultSet results = qe.execSelect();
ResultSetFormatter.out(System.out, results, query);
qe.close();