Hi. I'm Mark Wallace. In my role as a an Ontologist and Software Architect, I am continually working with new and fun semantic technologies. Be it RDF/OWL, Triple-stores, Semantic Wikis, or Text Extraction, I am learning more all the time and want to share my experiences in hopes of helping others along with these technologies. I hope post a new article every month or two, so check back in every so often to see what’s cooking!

Thursday, May 31, 2012

SPARQL query from JavaScript

There are JavaScript libraries out there for SPARQL, but it's actually quite simple to query SPARQL from JavaScript without using any special library.  Here is an example of making a SPARQL query directly from a web page using JavaScript.

<html> 
  <head> 
    <title> SPARQL JavaScript </title>
    <script>
    /**
     * Author: Mark Wallace
     *
     * This function asynchronously issues a SPARQL query to a
     * SPARQL endpoint, and invokes the callback function with the JSON 
     * Format [1] results.
     *
     * Refs:
     * [1] http://www.w3.org/TR/sparql11-results-json/
     */
    function sparqlQueryJson(queryStr, endpoint, callback, isDebug) {
      var querypart = "query=" + escape(queryStr);
    
      // Get our HTTP request object.
      var xmlhttp = null;
      if(window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
     } else if(window.ActiveXObject) {
       // Code for older versions of IE, like IE6 and before.
       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
     } else {
       alert('Perhaps your browser does not support XMLHttpRequests?');
     }
    
     // Set up a POST with JSON result format.
     xmlhttp.open('POST', endpoint, true); // GET can have caching probs, so POST
     xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
     xmlhttp.setRequestHeader("Accept", "application/sparql-results+json");
    
     // Set up callback to get the response asynchronously.
     xmlhttp.onreadystatechange = function() {
       if(xmlhttp.readyState == 4) {
         if(xmlhttp.status == 200) {
           // Do something with the results
           if(isDebug) alert(xmlhttp.responseText);
           callback(xmlhttp.responseText);
         } else {
           // Some kind of error occurred.
           alert("Sparql query error: " + xmlhttp.status + " "
               + xmlhttp.responseText);
         }
       }
     };
     // Send the query to the endpoint.
     xmlhttp.send(querypart);
    
     // Done; now just wait for the callback to be called.
    };
    </script>
  </head>

  <body>
    <script>
      var endpoint = "http://dbpedia.org/sparql";
      var query = "select * {?s ?p ?o} limit 5" ;

      // Define a callback function to receive the SPARQL JSON result.
      function myCallback(str) {
        // Convert result to JSON
        var jsonObj = eval('(' + str + ')');

        // Build up a table of results.
        var result = " <table border='2' cellpadding='9'>" ;
        for(var i = 0; i<  jsonObj.results.bindings.length; i++) {
          result += " <tr> <td>" + jsonObj.results.bindings[i].s.value;
          result += " </td><td>" + jsonObj.results.bindings[i].p.value;
          result += " </td><td>" + jsonObj.results.bindings[i].o.value;
          result += " </td></tr>"; 
        } 
        result += "</table>" ;
        document.getElementById("results").innerHTML = result;
     }
      
     // Make the query.
     sparqlQueryJson(query, endpoint, myCallback, true);
      
    </script>

    <div id="results">
      It may take a few moments for the info to be displayed here...
      <br/><br/>
      Run me in Internet Explorer or I get Cross Domain HTTP Request errors!
    </div>
  
  </body>
</html>

 
In the head section, the code defines a function, sparqlQueryJson(), that takes a SPARQL query string, a SPARQL endpoint URL, and a function to call when the result is ready.  (The optional fourth parameter will show you the raw JSON SPARQL results in an alert window if you set it to true.)  In the body section, the code specifies the query string, endpoint, and callback function, and then calls sparqlQueryJson() to issue the request.

Put the above code in a file called sparql.htm, and give it a try in your browser!

A few things to note:
  1. Most browsers won't let you run this code because it makes a cross-domain request (calls a service on a different host than the HTML was served from).  Use IE and if/when prompted, allow the content. 
  2. I use an asynchronous XMLHttpRequest to perform the query to the SPARQL endpoint.
  3. It would be best to put the sparqlQueryJson() function in a separate file to make it reusable from multiple pages.  I put everything in one file here just to simplify the example slightly. 



6 comments:

  1. Spot on with this write-up, I actually think this website wants way more consideration.
    I’ll probably be once more to learn much
    more, thanks for that info.
    My webpage ; schimmel messgerät

    ReplyDelete
  2. I truly like to reading your post. Thank you so much for taking the time to share such a nice information.
    web grid

    ReplyDelete
  3. Mark, very succinct; however, when I try this against my sesame repository, I keep getting Access-Control-Allow-Origin errors. Any clues?

    ReplyDelete
  4. Well, first of all thanks a lot for your post.
    I was trying to test it , but as you said it is only accessible through IE, my question is is there any way to expand this code to work with Firefox & Chrome?

    ReplyDelete
  5. I'd love a similar server-side example :]

    ReplyDelete
  6. Hi, Thanks for this post! I Do you have an example for querying allegrograph triple store through javascript? I have looked around quiet a bit, but cannot find an exposed sparql end point for allegrograph.

    ReplyDelete

Followers