Mercurial > repos > guerler > springsuite
diff planemo/lib/python3.7/site-packages/rdflib/plugins/sparql/results/xmlresults.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:32:28 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/planemo/lib/python3.7/site-packages/rdflib/plugins/sparql/results/xmlresults.py Fri Jul 31 00:32:28 2020 -0400 @@ -0,0 +1,258 @@ + +from xml.sax.saxutils import XMLGenerator +from xml.dom import XML_NAMESPACE +from xml.sax.xmlreader import AttributesNSImpl + +from rdflib.compat import etree + +from rdflib import Literal, URIRef, BNode, Graph, Variable +from rdflib.query import ( + Result, + ResultParser, + ResultSerializer, + ResultException +) + +SPARQL_XML_NAMESPACE = 'http://www.w3.org/2005/sparql-results#' +RESULTS_NS_ET = '{%s}' % SPARQL_XML_NAMESPACE + + +"""A Parser for SPARQL results in XML: + +http://www.w3.org/TR/rdf-sparql-XMLres/ + +Bits and pieces borrowed from: +http://projects.bigasterisk.com/sparqlhttp/ + +Authors: Drew Perttula, Gunnar Aastrand Grimnes +""" + + +class XMLResultParser(ResultParser): + + def parse(self, source): + return XMLResult(source) + + +class XMLResult(Result): + def __init__(self, source): + + xmlstring = source.read() + + if isinstance(xmlstring, str): + xmlstring = xmlstring.encode('utf-8') + try: + tree = etree.fromstring(xmlstring) + except Exception as e: + try: + raise e.__class__("error parsing %r: %s" % (xmlstring, e)) + except: + raise e + + boolean = tree.find(RESULTS_NS_ET + 'boolean') + results = tree.find(RESULTS_NS_ET + 'results') + + if boolean is not None: + type_ = 'ASK' + elif results is not None: + type_ = 'SELECT' + else: + g = Graph() + try: + g.parse(data=xmlstring) + if len(g) == 0: + raise + type_ = 'CONSTRUCT' + + except: + raise ResultException( + "No RDF Graph, result-bindings or boolean answer found!") + + Result.__init__(self, type_) + if type_ == 'SELECT': + self.bindings = [] + for result in results: + r = {} + for binding in result: + r[Variable(binding.get('name'))] = parseTerm(binding[0]) + self.bindings.append(r) + + self.vars = [Variable(x.get("name")) + for x in tree.findall( + './%shead/%svariable' % ( + RESULTS_NS_ET, RESULTS_NS_ET))] + + elif type_ == 'ASK': + self.askAnswer = boolean.text.lower().strip() == "true" + elif type_ == 'CONSTRUCT': + self.graph = g + + +def parseTerm(element): + """rdflib object (Literal, URIRef, BNode) for the given + elementtree element""" + tag, text = element.tag, element.text + if tag == RESULTS_NS_ET + 'literal': + if text is None: + text = '' + datatype = None + lang = None + if element.get('datatype', None): + datatype = URIRef(element.get('datatype')) + elif element.get("{%s}lang" % XML_NAMESPACE, None): + lang = element.get("{%s}lang" % XML_NAMESPACE) + + ret = Literal(text, datatype=datatype, lang=lang) + + return ret + elif tag == RESULTS_NS_ET + 'uri': + return URIRef(text) + elif tag == RESULTS_NS_ET + 'bnode': + return BNode(text) + else: + raise TypeError("unknown binding type %r" % element) + + +class XMLResultSerializer(ResultSerializer): + + def __init__(self, result): + ResultSerializer.__init__(self, result) + + def serialize(self, stream, encoding="utf-8"): + + writer = SPARQLXMLWriter(stream, encoding) + if self.result.type == 'ASK': + writer.write_header([]) + writer.write_ask(self.result.askAnswer) + else: + writer.write_header(self.result.vars) + writer.write_results_header() + for b in self.result.bindings: + writer.write_start_result() + for key, val in b.items(): + writer.write_binding(key, val) + + writer.write_end_result() + + writer.close() + + +# TODO: Rewrite with ElementTree? +class SPARQLXMLWriter: + """ + Python saxutils-based SPARQL XML Writer + """ + def __init__(self, output, encoding='utf-8'): + writer = XMLGenerator(output, encoding) + writer.startDocument() + writer.startPrefixMapping('', SPARQL_XML_NAMESPACE) + writer.startPrefixMapping('xml', XML_NAMESPACE) + writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'sparql'), + 'sparql', AttributesNSImpl({}, {})) + self.writer = writer + self._output = output + self._encoding = encoding + self._results = False + + def write_header(self, allvarsL): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'head'), + 'head', AttributesNSImpl({}, {})) + for i in range(0, len(allvarsL)): + attr_vals = { + (None, 'name'): str(allvarsL[i]), + } + attr_qnames = { + (None, 'name'): 'name', + } + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'variable'), + 'variable', AttributesNSImpl(attr_vals, attr_qnames)) + self.writer.endElementNS((SPARQL_XML_NAMESPACE, + 'variable'), 'variable') + self.writer.endElementNS((SPARQL_XML_NAMESPACE, 'head'), 'head') + + def write_ask(self, val): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'boolean'), + 'boolean', AttributesNSImpl({}, {})) + self.writer.characters(str(val).lower()) + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'boolean'), 'boolean') + + def write_results_header(self): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'results'), + 'results', AttributesNSImpl({}, {})) + self._results = True + + def write_start_result(self): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'result'), + 'result', AttributesNSImpl({}, {})) + self._resultStarted = True + + def write_end_result(self): + assert self._resultStarted + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'result'), 'result') + self._resultStarted = False + + def write_binding(self, name, val): + assert self._resultStarted + + attr_vals = { + (None, 'name'): str(name), + } + attr_qnames = { + (None, 'name'): 'name', + } + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'binding'), + 'binding', AttributesNSImpl(attr_vals, attr_qnames)) + + if isinstance(val, URIRef): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'uri'), + 'uri', AttributesNSImpl({}, {})) + self.writer.characters(val) + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'uri'), 'uri') + elif isinstance(val, BNode): + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'bnode'), + 'bnode', AttributesNSImpl({}, {})) + self.writer.characters(val) + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'bnode'), 'bnode') + elif isinstance(val, Literal): + attr_vals = {} + attr_qnames = {} + if val.language: + attr_vals[(XML_NAMESPACE, 'lang')] = val.language + attr_qnames[(XML_NAMESPACE, 'lang')] = "xml:lang" + elif val.datatype: + attr_vals[(None, 'datatype')] = val.datatype + attr_qnames[(None, 'datatype')] = 'datatype' + + self.writer.startElementNS( + (SPARQL_XML_NAMESPACE, 'literal'), + 'literal', AttributesNSImpl(attr_vals, attr_qnames)) + self.writer.characters(val) + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'literal'), 'literal') + + else: + raise Exception("Unsupported RDF term: %s" % val) + + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'binding'), 'binding') + + def close(self): + if self._results: + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'results'), 'results') + self.writer.endElementNS( + (SPARQL_XML_NAMESPACE, 'sparql'), 'sparql') + self.writer.endDocument()