How run SPIN queries against a SPARQL endpoint?

277 views
Skip to first unread message

Las

unread,
Jul 1, 2011, 6:45:37 AM7/1/11
to TopBraid Suite Users
Hi,

just started playing with SPIN 1.2, and I'm a bit overwhelmed.

Basically, I've managed to load a serialized SPIN template. [1] I'd
like to set the free template variables and run it against a SPARQL
endpoint without loading all it's triples into memory (Jena Model).

Can anybody give me some pointers how to do that?

Thx,
Las

[1] http://semwebquality.org/ontologies/dq-constraints#FiveDigitNumericAll

Scott Henninger

unread,
Jul 1, 2011, 7:50:12 AM7/1/11
to TopBraid Suite Users
Las; You should be able to run the SPARQL query against an endpoint
using the SERVICE keyword. E.g.:

CONSTRUCT{
_:b0 a spin:ConstraintViolation .
_:b0 spin:violationRoot ?s .
_:b0 spin:violationPath ?arg1 .
}
WHERE{
SERVICE <service-uri>
{ ?s ?arg1 ?value .
FILTER (!regex(str(?value), "^[0-9]{5}$"^^xsd:string))
}
}

If you're overwhelmed by the SPIN API, you may want to download TBC-SE/
ME/Free (http://www.topquadrant.com/products/TB_install.php) to
experiment with SPIN features before jumping headlong into the API.

-- Scott

László Török

unread,
Jul 1, 2011, 9:21:18 AM7/1/11
to topbrai...@googlegroups.com
Hi Scott,

thanks, I think I'm sufficiently comfortable with TBC. What I don't quite grok yet, is how to do even simple things programmatically.

Given the example SPIN template below, I'd like to replace the template variable with an actual property (which is a resource).

Well, I can surely call toString() on Template to get the SPARQL query as string and do some regex magic, but there has to be a more elegant way. The javadoc is not very intuitive unfortunatelly. Any pointers how to do that? (TBC must be doing it somehow too.. :), no I'm not developing a TBC clone :) )

Thanks,

Las

2011/7/1 Scott Henninger <shenn...@topquadrant.com>
--
You received this message because you are subscribed to the Google
Group "TopBraid Suite Users", the topics of which include TopBraid Composer,
TopBraid Live, TopBraid Ensemble, SPARQLMotion and SPIN.
To post to this group, send email to
topbrai...@googlegroups.com
To unsubscribe from this group, send email to
topbraid-user...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/topbraid-users?hl=en



--
László Török

Skype: laczoka2000
Twitter: @laczoka

Holger Knublauch

unread,
Jul 4, 2011, 7:05:07 PM7/4/11
to topbrai...@googlegroups.com
Hi László,

I have just added a small example of the SPIN API to create and invoke a SPIN template.

The key idea is to use pre-binding of variables in the Jena QueryExecution:

com.hp.hpl.jena.query.Query arq = ARQFactory.get().createQuery((Select)template.getBody());
QueryExecution qexec = ARQFactory.get().createQueryExecution(arq, model);
QuerySolutionMap arqBindings = new QuerySolutionMap();
arqBindings.add("predicate", RDFS.label);
qexec.setInitialBinding(arqBindings); // Pre-assign the arguments
ResultSet rs = qexec.execSelect();

The full source code is attached. Please follow up if this doesn't cover your use case.

Regards,
Holger
TemplateExample.java

László Török

unread,
Jul 6, 2011, 4:51:51 AM7/6/11
to topbrai...@googlegroups.com
Hi Holger,

thanks, it was giant leap towards the solution. However, it is important that I can run the instantiated template query against an external SPARQL endpoint, as seen in the following snippet.


        Query arqQuery = ARQFactory.get().createQuery((org.topbraid.spin.model.Construct)templ.getBody());
        List<String> sparqlEndpoint = new ArrayList<String>();
        sparqlEndpoint.add("http://edgy:8890/sparql");
       
        QueryEngineHTTP qexec = ARQFactory.get().createRemoteQueryExecution(arqQuery, sparqlEndpoint);

       
        QuerySolutionMap arqBindings = new QuerySolutionMap();
        arqBindings.add("predicate", RDFS.label);
        arqBindings.add("arg1", postalCodeProp);
       
        qexec.setInitialBinding(arqBindings);
        qexec.execConstruct(newTriples);

ISSUE: QueryEngineHTTP doesn't not implement setInitialBinding. :( An alternative could be (as I've heard), to add SERVICE to the query. However, I didn't find a way to do it using some factory or fluent builder in the API. I could surely resort to toString() and some regex or String.replace magic, but then SPIN API would be degraded to a SPARQL serialization library in the given scenario.

Let me know what you think.

Thanks,

Las


2011/7/5 Holger Knublauch <hol...@topquadrant.com>

Holger Knublauch

unread,
Jul 6, 2011, 5:44:38 AM7/6/11
to topbrai...@googlegroups.com
Hi Laszlo,

for help and clarification why remote query executions don't support pre-bindings, you may need to follow up with the Jena mailing list. However, there is a solution with the SPIN API that allows you to pre-bind variables at serialization time. The effect is that when you have a SPIN RDF object (Query) you can set variables in the PrintContext and this will create a query string where the variables have been replaced with the values. I am not 100% sure that this covers all cases, but it might work in your scenarios. Something like

StringBuilder sb = new StringBuilder();
StringPrintContext c = new StringPrintContext(sb, initialBindings);
query.print(c);
String arqString = sb.toString();

would give you a string that you can then convert to a remote Jena query.

Cheers,
Holger

Amit Jain

unread,
Oct 18, 2011, 3:32:55 AM10/18/11
to topbrai...@googlegroups.com
Hi 
I am trying to do the same, getting a template stored in SPIN RDF format, get the SPIN query object and then get the sparql query with the variables in the template replaced with the runtime arguments. Now java source code attached in this thread does allow using jena QueryExecution to run the ARQ query on a model, this does not allow using other non-jena systems. Hence i want to be able to get the actual Sparql query with the replaced arguments and use it. Using the string builder and stringprintcontext gives me back the original query with the variables only.
thanks for the help
-amit

Holger Knublauch

unread,
Oct 18, 2011, 4:52:30 AM10/18/11
to topbrai...@googlegroups.com
Hi Amit,

if you pass in the pre-bound variables as initialBindings, then the printed string will have the variables replaced, and you can use the string in non-Jena systems. If this does not work, I would need to see your source code.

Thanks
Holger

Amit Jain

unread,
Oct 18, 2011, 7:17:24 AM10/18/11
to topbrai...@googlegroups.com
Hi Holger
Thanks for the quick reply. Here are the source lines:

Map<String,RDFNode> map = new HashMap<String,RDFNode>();

map.put("predicate",RDF.Type);

Template templ = SPINFactory.asTemplate(sub);
com.hp.hpl.jena.query.Query arqQ = ARQFactory.get().createQuery((Select)templ.getBody());
org.topbraid.spin.model.Query spinQuery = new ARQ2SPIN(model).createQuery(arqQ, null);

StringBuilder queryBldr = new StringBuilder(); 
StringPrintContext printCntxt = new StringPrintContext(queryBldr,map);

spinQuery.print(printCntxt); 

String sparqlStr = queryBldr.toString();
System.out.println(sparqlStr);


It still gives me the query with variables.
thanks
-amit

Holger Knublauch

unread,
Oct 18, 2011, 11:21:32 PM10/18/11
to topbrai...@googlegroups.com
On Oct 18, 2011, at 9:17 PM, Amit Jain wrote:

Hi Holger
Thanks for the quick reply. Here are the source lines:

Map<String,RDFNode> map = new HashMap<String,RDFNode>();

map.put("predicate",RDF.Type);

Template templ = SPINFactory.asTemplate(sub);
com.hp.hpl.jena.query.Query arqQ = ARQFactory.get().createQuery((Select)templ.getBody());
org.topbraid.spin.model.Query spinQuery = new ARQ2SPIN(model).createQuery(arqQ, null);

Here you are creating a clone of the SPIN RDF structure that is already present at the template. Please try

org.topbraid.spin.model.Command spinQuery = templ.getBody();

instead. The rest looks OK and should work. How does your template body look like?

Holger

Amit Jain

unread,
Oct 19, 2011, 4:15:45 AM10/19/11
to topbrai...@googlegroups.com
Hi Holger,
It did not work. I am still getting just the query template, though the RDFNode node gives me the RDF.bag but not in the sparql query. Here is the template body.

@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .

@prefix arg:     <http://spinrdf.org/arg#> .

@prefix owl:     <http://www.w3.org/2002/07/owl#> .

@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .

@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

@prefix ex:   <http://example.com/onto#> .


<ex:testTempl>

      a       <http://spinrdf.org/spin#Template> ;

      <http://spinrdf.org/spin#body>

              [ a       <http://spinrdf.org/sp#Select> ;

                <http://spinrdf.org/sp#where>

                        ([ <http://spinrdf.org/sp#object>

                                    [ <http://spinrdf.org/sp#varName>

                                              "object"^^xsd:string

                                    ] ;

                            <http://spinrdf.org/sp#predicate>

                                    [ <http://spinrdf.org/sp#varName>

                                              "ssn"^^xsd:string

                                    ] ;

                            <http://spinrdf.org/sp#subject>

                                    [ <http://spinrdf.org/sp#varName>

                                              "sub"^^xsd:string

                                    ]

                          ])

              ] ;

      <http://spinrdf.org/spin#constraint>

              [ a       <http://spinrdf.org/spl#Argument> ;

                rdfs:comment "SSN value " ;

                <http://spinrdf.org/spl#predicate>

                        arg:ssn ;

                <http://spinrdf.org/spl#valueType>

                        rdf:Property

              ] .


and the modified code is 

Map<String,RDFNode> map1 = new HashMap<String,RDFNode>();

map1.put("predicate",RDF.Bag);


....

Template templ = SPINFactory.asTemplate(sub);

org.topbraid.spin.model.Command spinQuery = templ.getBody(); 

StringBuilder queryBldr = new StringBuilder(); 

StringPrintContext printCntxt = new StringPrintContext(queryBldr,map1);

RDFNode rnode = printCntxt.getInitialBinding("predicate");

System.out.println("node:  "+rnode);

spinQuery.print(printCntxt); 

sparqlStr = queryBldr.toString(); 

System.out.println(sparqlStr);

thanks
-amit 

Holger Knublauch

unread,
Oct 19, 2011, 5:01:50 AM10/19/11
to topbrai...@googlegroups.com
I guess you meant put("ssn", ... )  - there is no variable "predicate" in your query.

Holger

Reply all
Reply to author
Forward
0 new messages