1

I want to write a query similar to this --

select ?s ?p ?o where {?s ?p ?o. ?s rdf:subClassOf + mySpecificSubjectValue +}

Is there any existing way to do this? Or Do I have to do it manually by checking all subjects. And also I don't want to use regex in query cause regex create some problems for example: base:hotel and base:hotelName

  • *"Is there any existing way to do this?"* -> May I ask you what you're asking for now? Did you read the documentation? I mean, it's just sending the query string, isn't it? You didn't show any code nor sample data. I hope you know that `mySpecificSubjectValue` must be a class? – UninformedUser Sep 22 '18 at 06:50
  • *"Or Do I have to do it manually by checking all subjects."* - what does this question mean? – UninformedUser Sep 22 '18 at 06:51
  • *"And also I don't want to use regex in query cause regex create some problems for example: base:hotel and base:hotelName"* - I don't see any regex in your query, again it's not clear what you're doing – UninformedUser Sep 22 '18 at 06:51
  • By the way, it's called `rdfs:subClassOf`... – UninformedUser Sep 22 '18 at 06:52
  • What I am trying express is: For example, I have this dataset http://www.base.org/hotel rdfs:type base:hotel http://www.base.org/hotel rdfs:label "something" http://www.base.org/hotelArea rdfs:type base:hotelArea http://www.base.org/hotelArea rdfs:label "something" I want to extract all triples of hotel, not hotelArea. I don't want to use regex. I know the way of querying with regex. I am asking if there is a way to pass the variable in the query. – Amrit Bhattacharjee Sep 22 '18 at 07:18
  • What prevents you from creating the query string on demand? I mean it's just concatenating the strings, or not? If you want to have it more convenient, use [`ParameterizedSparqlString`](http://jena.apache.org/documentation/javadoc/arq/org/apache/jena/query/ParameterizedSparqlString.html) with e.g. `ParameterizedSparqlString q = new ParameterizedSparqlString("select * {?s a base:hotel; ?s rdfs:label ?label}");` and then call `q.setLiteral("label", "something");` – UninformedUser Sep 22 '18 at 12:28

1 Answers1

0

Jena has a set of classes useful to build a query instance. Here is an example that builds a query like yours:

String yourclassuri =  "base:hotel" ;
    //Intialize the select statatment
    Query select = new Query();

    //set prefixes
    select.setPrefix("rdf","rdfurl");
    select.setPrefix("base","yourbaseurl");

    select.setQuerySelectType();
    select.addResultVar("s");
    select.addResultVar("p");
    select.addResultVar("o");

    final ElementPathBlock elementPathBlock = new ElementPathBlock();

    //create the first pattern in the where
    final Node s = NodeFactory.createVariable("s");
    final Node p = NodeFactory.createVariable("p");
    final Node o = NodeFactory.createVariable("o");
    elementPathBlock.addTriple(new Triple(s,p,o));

    //create the last pattern
    final Node subclass = NodeFactory.createURI("rdf:subClassOf");
    final Node rdfclass = NodeFactory.createURI(yourclassuri);
    elementPathBlock.addTriple(new Triple(s,subclass,rdfclass));

    select.setQueryPattern(elementPathBlock);

    //serialize the query in a string
    String query = select.serialize();

    //output select ?s ?p ?o where {?s ?p ?o. ?s rdf:subClassOf base:hotel}

Sources: Jena javadoc

Notice that you can use a ParametrizedSparqlString but it seems ineffective when you want to inject prefixed names (like base:name). The Javadoc also warns about possible SPARQL inject problems:

SPARQL Injection Notes

While this class was in part designed to prevent SPARQL injection it is by no means foolproof because it works purely at the textual level. The current version of the code addresses some possible attack vectors that the developers have identified but we do not claim to be sufficiently devious to have thought of and prevented every possible attack vector.

I suspect that query building is a bit more safer against this kind of attacks. Also here it is an other aswer about the limits of ParameterizedSparqlString.

Cristiano
  • 534
  • 6
  • 21
  • 1
    well, I don't think is what she was asking for (besides that the question is not rellz clear to me). from my point of view, is much simpler to use just a Java String. And if something like a template query is needed, [`ParameterizedSparqlString`](http://jena.apache.org/documentation/javadoc/arq/org/apache/jena/query/ParameterizedSparqlString.html) is the way to go. – UninformedUser Sep 22 '18 at 11:14
  • 1
    based on her last comment I was thinking about a parametrized query... Anyway I didn't know about ParameterizedSparqlString. I agree that in this case it fits better, then build the entire query. I'll update the answer with your suggestion! Thank you. – Cristiano Sep 22 '18 at 11:55
  • I've found that there's no method to effectively inject a prefixed name in a query template using ParametrizeSparqlString. `setIri("var","name:value")` method inject `` which is not a valid SPARQL GraphNode. See also this answer https://stackoverflow.com/a/43020661/925955 for further details. – Cristiano Sep 22 '18 at 12:34
  • String sparql = "SELECT DISTINCT ?s WHERE { ?s rdfs:subClassOf ?object.}"; ParameterizedSparqlString queryStr = new ParameterizedSparqlString(sparql); String value = "http://www.something.org/ontology#Feature"; queryStr.setIri("object", value); It is showing all the classes with the property rdfs:subClassOf. What am I doing wrong? – Amrit Bhattacharjee Sep 22 '18 at 14:20
  • Have you checked that the parameter is actually substituted? Other than that I've no clue, sorry. Have you tried the query builder approach? – Cristiano Sep 24 '18 at 12:58