Introduction

The W3C's Data Access Working Group is charged with designing a query language and data-access protocol for retrieving information from RDF data stores and knowledgebases. The SPARQL Protocol is normatively described by means of a set of WSDL 2.0 definitions.

To facilitate the creation of SPARQL Protocol clients and endpoints using existing tooling, the Working Group has also published an informative Working Draft describing the SPARQL Protocol via a set of WSDL 1.1 definitions.

The Working Group intends this page to host samples of using the WSDL 1.1 document with various toolkits to generate code to implement the SPARQL Protocol.

Using Axis's WSDL2Java

SPARQLClient is an example SPARQL Protocol client that uses Apache Axis's WSDL2Java to run SPARQL queries against a (not provided) SPARQL Protocol endpoint using SOAP over HTTP.

The archive contains the following folders and files:

SOAP/sparql-11-example-port.wsdl

The WSDL 1.1 provided in the Working Group Note contains the types, faults, operations, and interface (port type) that define the abstract SPARQL Protocol. For sample code to connect to a concrete endpoint implementing the main SparqlQueryInterface port type, we need a supplementary WSDL file defining a service with a port that specifies a specific address of an endpoint. SOAP/sparql-11-example-port.wsdl, then, performs two functions:

  1. Import the WSDL 1.1 defining the SOAP bindings for SparqlQueryInterface:

  <wsdl:import namespace="http://www.w3.org/2005/08/sparql-protocol-query/#"
               location="http://www.w3.org/2001/sw/DataAccess/proto-wsdl11/sparql-protocol-query-11.wsdl"/>
  1. Define a sample service and port with binding information specifying SOAP over HTTP and pointing to the URL of our sample endpoint:

  <wsdl:service name="SPARQLQueryService">
    <wsdl:port binding="bindings:QuerySoapBinding" name="sparql-query">
      <soap:address location="http://localhost:2525/axis/services/sparql-query"/>
    </wsdl:port>
  </wsdl:service>

SOAP/build.xml

This is an Ant build configuration file. Its default task, sparql-11-wsdl uses the WSDL2Java Ant task to generate source code from the WSDL and imported XML Schema files. The sparql-11-wsdl task outputs both classes to invoke the SPARL Protocol query operation against a specific service endpoint as well as bean classes to represent the types involved as inputs to and outputs from the operation.

The source code generated from the sparql-11-wsdl task is output in a folder hierarchy in SOAP/src-soap.

src/RunClient.java

This stitches together the generated code to invoke the SPARQL Protocol endpoint given in SOAP/sparql-11-example-port.wsdl and interpret the results. It issues two queries: a SELECT query followed by a CONSTRUCT query. Here we walkthrough the code that issues a query in it the order it executes at runtime.

    static String endpoint = "http://localhost:2525/axis/services/sparql-query" ;
    ...   
    public static void runQuery(String query, String 
        // Setup our service to point to our endpoint
        SPARQLQueryServiceLocator  service = new SPARQLQueryServiceLocator();
        service.setSparqlQueryEndpointAddress(endpoint);
     
        // Retrieve a reference to the SparqlQuery interface
        SparqlQueryInterface soapQuery = null;
        try {
            soapQuery = service.getSparqlQuery() ;
        } catch (javax.xml.rpc.ServiceException ex) { 
                throw new RuntimeException("Query exception: " + ex.getMessage()) ; 
        }

        // We register a stub class to deserialize RDF/XML
        // so that Axis does not complain. A "real" implementation
        // would use a deserialization class that parses the RDF/XML
        // into an appropriate graph representation. Our deserializer
        // simply returns a string representation of the RDF/XML returned.
        TypeMappingRegistry reg = service.getEngine().getTypeMappingRegistry() ;
        TypeMapping tm = (TypeMapping)reg.getTypeMapping("") ;
        tm.register(
            String.class, // the type to deserialize to
            new QName("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "RDF") ,
            null,         // SerializerFactory
            new SimpleDeserializerFactory()
        );

        QueryRequest q = new QueryRequest() ;
        q.setQuery(query) ;
        // Any default graphs or named graphs would be set here
        //q.setDefaultGraphUri(new URI[] { ... });
        //q.setNamedGraphUri(new URI[] { ... });

        QueryResult result = null;
        try {
            result =  soapQuery.query(q) ;
        } catch (MalformedQuery ex) {
            throw new RuntimeException("Malformed query fault: " + ex.getFaultString(), ex) ;
        } catch (QueryRequestRefused refused) {
                throw new RuntimeException("Query request refused fault: " + refused.getFaultString(), refused);
        } catch (AxisFault axisFault) {
            throw new RuntimeException("Axis Fault: "+axisFault.getFaultString(), axisFault); 
        } catch (RemoteException e) {
            throw new RuntimeException("Remote Exception: "+e.getMessage(), e) ; 
        }

        // Switch on the type of the result received and act accordingly.
        if (result.getRDF() != null) {
                System.out.println("RDF/XML returned:");
                // In this example, the result of deserializing RDF/XML is simply a string  
                System.out.println(result.getRDF());
        } else if (result.getSparql() != null) {
                System.out.println("VBR returned.");
                // Beans are generated for the SPARQL Query Results XML Format schema,
                // so we can use them to walk through our resultset.
                Sparql sparql = result.getSparql();
                if (sparql.get_boolean() == null) {
                        Results results = sparql.getResults();
                        System.out.println("SELECT returned " + results.getResult().length + " rows");
                } else {
                        System.out.println("ASK result is: " + sparql.get_boolean());
                }
        } else {
                System.out.println("Something else ?? returned.");
        }

Running the SPARQLClient Sample

To run the sample, change

    static String endpoint = "http://localhost:2525/axis/services/sparql-query" ;

to point to an actual SOAP-over-HTTP endpoint. (A listing of any publically available SOAP SPARQL endpoints would be great!) Then simply compile and run the RunClient class as a Java application to see the sample in action.

Using .Net's Web References

Using Python

SparqlProtocolWsdl11Examples (last edited 2006-06-28 13:41:05 by 209)