#!/usr/bin/ruby # all based on ivan's python ... module SPARQL # Wrapper around an a query result. Users should not create instances of this class, it is # generated by a L{SPARQLWrapper.query} call. The results can be # converted to various formats, or used directly. # If used directly: the class gives access to the direct http request results # L{self.response}: is a file-like object with two additional methods: C{geturl()} to # return the URL of the resource retrieved and # C{info()} that returns the meta-information of the HTTP result, as a dictionary-like object # (see the urllib2 standard library module of Python). # # For convenience, these methods are also available on the class level. The C{__iter__} and # C{next} methods are also implemented (by mapping them to L{self.response}). This means that the # common idiom:: # for l in obj : do_something_with_line(l) # would work, too. class QueryResult attr_accessor :response # @param response: HTTP response stemming from a L{SPARQLWrapper.query} call # Direct response, see class comments for details def initialize(response) self.response = response end # Return the URI leading to this result # @return: URI # @rtype: string def geturl() return self.response.geturl() end # Return the meta-information of the HTTP result # @return: meta information # @rtype: dictionary def info() return self.response.info() end # Return an iterator object. This method is expected for the inclusion # of the object in a standard C{for} loop. def __iter__() return self.response.__iter__() end # Method for the standard iterator. def next() return self.response.next() end # Convert a JSON result into Ruby objects. # @return: converted result # @rtype: Python dictionary def _convertJSON() js="" begin gem "json" js = JSON.parse(self.response) rescue puts "Error during JSON. #{$!}" end return js end # Convert an XML result into a Python dom tree. This method can be overwritten in a # subclass for a different conversion method. # @return: converted result # @rtype: PyXlib DOM node def _convertXML() require 'rexml/document' return REXML::Document.new(self.response) raise "Unimplemented." # from xml.dom.ext.reader import PyExpat # Parser = PyExpat.Reader # except ImportError : # from xml.dom.ext.reader import Sax2 # Parser = Sax2.Reader # #import warnings # #warnings.warn("Expat parser could not be loaded, using Sax2. Might slow down things...") # reader = Parser() # return reader.fromStream(self.response) end # Convert an RDF/XML result into an RDFLib triple store. This method can be overwritten # in a subclass for a different conversion method. # @return: converted result # @rtype: RDFLib Graph def _convertRDF() raise "Unimplemented." # from rdflib import Graph # retval = Graph() # # this is a strange hack. If the publicID is not set, rdflib (or the underlying xml parser) makes a funny # #(and, as far as I could see, meaningless) error message... # retval.load(self.response,publicID=' ') # return retval end # Convert an RDF N3 result into a string. This method can be overwritten in a subclass # for a different conversion method. # @return: converted result # @rtype: string def _convertN3() retval = "" self.response.each do |l| retval += l end return retval end # Encode the return value depending on the return format: # - in the case of XML, a minidom top level is returned # - in the case of JSON, a simplejson conversion will return a dictionary # - in the case of RDF/XML, the value is converted via RDFLib # in all other cases the input simply returned. # # @return: the converted query result. See the conversion methods for more details. def convert() raise "Unimplemented." # ct = self.response.info()["content-type"] # if True in [ct.find(q) != -1 for q in _SPARQL_XML] : # return self._convertXML() # elif True in [ct.find(q) != -1 for q in _SPARQL_JSON] : # return self._convertJSON() # elif True in [ct.find(q) != -1 for q in _RDF_XML] : # return self._convertRDF() # elif True in [ct.find(q) != -1 for q in _RDF_N3] : # return self._convertN3() # else : # # this should cover, well, the rest of the cases... # return self.response # end end end