/* -*- Mode: c; c-basic-offset: 2 -*- * * rasqal_query.c - Rasqal RDF Query Results * * $Id: rasqal_query_results.c 11551 2006-10-29 21:12:27Z dajobe $ * * Copyright (C) 2003-2006, David Beckett http://purl.org/net/dajobe/ * Copyright (C) 2003-2005, University of Bristol, UK http://www.bristol.ac.uk/ * * This package is Free Software and part of Redland http://librdf.org/ * * It is licensed under the following three licenses as alternatives: * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version * 2. GNU General Public License (GPL) V2 or any newer version * 3. Apache License, V2.0 or any newer version * * You may not use this file except in compliance with at least one of * the above three licenses. * * See LICENSE.html or LICENSE.txt at the top of this package for the * complete terms and further detail along with the license texts for * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. * * */ #ifdef HAVE_CONFIG_H #include #endif #ifdef WIN32 #include #endif #include #include #ifdef HAVE_STDLIB_H #include #endif #include #include "rasqal.h" #include "rasqal_internal.h" static int rasqal_query_results_write_xml_20041221(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri); static int rasqal_query_results_write_xml_result2(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri); static int rasqal_query_results_write_xml_result3(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri); static int rasqal_query_results_write_json1(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri); static raptor_sequence* query_results_formats; static void rasqal_query_results_format_register_factory(const char *name, const char *label, const unsigned char* uri_string, rasqal_query_results_writer writer) { rasqal_query_results_format_factory* factory; factory=RASQAL_MALLOC(query_results_format_factory, sizeof(rasqal_query_results_format_factory)); factory->name=name; factory->label=label; factory->uri_string=uri_string; factory->writer=writer; raptor_sequence_push(query_results_formats, factory); } static void rasqal_free_query_results_format_factory(rasqal_query_results_format_factory* factory) { RASQAL_FREE(query_results_format_factory, factory); } void rasqal_init_query_results(void) { rasqal_query_results_writer fn; query_results_formats=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_query_results_format_factory, NULL); /* * SPARQL XML Results 2006-01-25 * http://www.w3.org/TR/2006/WD-rdf-sparql-XMLres-20060125/ */ fn=&rasqal_query_results_write_xml_result3; rasqal_query_results_format_register_factory("xml", "SPARQL Query Results Format 2006-01-25", (unsigned char*)"http://www.w3.org/2005/sparql-results#", fn); rasqal_query_results_format_register_factory(NULL, NULL, (unsigned char*)"http://www.w3.org/TR/2006/WD-rdf-sparql-XMLres-20060125/", fn); /* * SPARQL XML Results 2005-05-27 * http://www.w3.org/TR/2005/WD-rdf-sparql-XMLres-20050527/ * http://www.w3.org/2001/sw/DataAccess/rf1/result2 */ fn=&rasqal_query_results_write_xml_result2; rasqal_query_results_format_register_factory("xml-v2", "SPARQL Query Results Format 2005-05-27", (unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result2", fn); rasqal_query_results_format_register_factory(NULL, NULL, (unsigned char*)"http://www.w3.org/TR/2005/WD-rdf-sparql-XMLres-20050527/", fn); /* * SPARQL XML Results 2004-12-21 * http://www.w3.org/TR/2004/WD-rdf-sparql-XMLres-20041221/ * http://www.w3.org/2001/sw/DataAccess/rf1/result */ fn=&rasqal_query_results_write_xml_20041221; rasqal_query_results_format_register_factory("xml-v1", "SPARQL Query Results Format 2004-12-21", (unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result", fn); rasqal_query_results_format_register_factory(NULL, NULL, (unsigned char*)"http://www.w3.org/TR/2004/WD-rdf-sparql-XMLres-20041221/", fn); /* * SPARQL Query Results in JSON (http://json.org/) draft * Defined in http://www.w3.org/2001/sw/DataAccess/json-sparql/ * Version: 1.6 $ of $Date: 2006/04/05 15:55:17 */ fn=&rasqal_query_results_write_json1; rasqal_query_results_format_register_factory("json", "JSON", (unsigned char*)"http://www.w3.org/2001/sw/DataAccess/json-sparql/", fn); rasqal_query_results_format_register_factory(NULL, NULL, (unsigned char*)"http://www.mindswap.org/%7Ekendall/sparql-results-json/", fn); } void rasqal_finish_query_results(void) { raptor_free_sequence(query_results_formats); } /* * rasqal_new_query_results: * @query: query object * * Internal - create a query result for a query * * Return value: a new query result object or NULL on failure **/ rasqal_query_results* rasqal_new_query_results(rasqal_query* query) { rasqal_query_results* query_results; query_results=(rasqal_query_results*)RASQAL_CALLOC(rasqal_query_results, 1, sizeof(rasqal_query_results)); query_results->query=query; rasqal_query_results_init(query_results); return query_results; } void rasqal_query_results_init(rasqal_query_results* query_results) { query_results->result_count=0; query_results->executed=0; query_results->abort=0; query_results->finished=0; query_results->failed=0; query_results->ask_result= -1; query_results->current_triple_result= -1; query_results->results_sequence=NULL; } /** * rasqal_free_query_results: * @query_results: #rasqal_query_results object * * Destructor - destroy a rasqal_query_results. * **/ void rasqal_free_query_results(rasqal_query_results* query_results) { rasqal_query* query=query_results->query; if(!query_results) return; if(query_results->executed) rasqal_engine_execute_finish(query_results); if(query_results->row) rasqal_engine_free_query_result_row(query_results->row); if(query_results->execution_data && query_results->free_execution_data) query_results->free_execution_data(query, query_results, query_results->execution_data); if(query_results->results_sequence) raptor_free_sequence(query_results->results_sequence); if(query_results->triple) rasqal_free_triple(query_results->triple); query=query_results->query; rasqal_query_remove_query_result(query, query_results); RASQAL_FREE(rasqal_query_results, query_results); } /** * rasqal_query_results_is_bindings: * @query_results: #rasqal_query_results object * * Test if rasqal_query_results is variable bindings format. * * Return value: non-0 if true **/ int rasqal_query_results_is_bindings(rasqal_query_results* query_results) { rasqal_query* query=query_results->query; return (query->verb == RASQAL_QUERY_VERB_SELECT); } /** * rasqal_query_results_is_boolean: * @query_results: #rasqal_query_results object * * Test if rasqal_query_results is boolean format. * * Return value: non-0 if true **/ int rasqal_query_results_is_boolean(rasqal_query_results* query_results) { rasqal_query* query=query_results->query; return (query->verb == RASQAL_QUERY_VERB_ASK); } /** * rasqal_query_results_is_graph: * @query_results: #rasqal_query_results object * * Test if rasqal_query_results is RDF graph format. * * Return value: non-0 if true **/ int rasqal_query_results_is_graph(rasqal_query_results* query_results) { rasqal_query* query=query_results->query; return (query->verb == RASQAL_QUERY_VERB_CONSTRUCT || query->verb == RASQAL_QUERY_VERB_DESCRIBE); } /** * rasqal_query_results_get_count: * @query_results: #rasqal_query_results query_results * * Get number of bindings so far. * * Return value: number of bindings found so far or < 0 on failure **/ int rasqal_query_results_get_count(rasqal_query_results* query_results) { rasqal_query* query; if(!query_results || query_results->failed) return -1; if(!rasqal_query_results_is_bindings(query_results)) return -1; query=query_results->query; if(query->offset > 0) return query_results->result_count - query->offset; return query_results->result_count; } /** * rasqal_query_results_next: * @query_results: #rasqal_query_results query_results * * Move to the next result. * * Return value: non-0 if failed or results exhausted **/ int rasqal_query_results_next(rasqal_query_results* query_results) { if(!query_results || query_results->failed || query_results->finished) return 1; if(!rasqal_query_results_is_bindings(query_results)) return 1; return rasqal_engine_execute_next(query_results); } /** * rasqal_query_results_finished: * @query_results: #rasqal_query_results query_results * * Find out if binding results are exhausted. * * Return value: non-0 if results are finished or query failed **/ int rasqal_query_results_finished(rasqal_query_results* query_results) { if(!query_results) return 1; if(!rasqal_query_results_is_bindings(query_results)) return 1; return (query_results->failed || query_results->finished); } /** * rasqal_query_results_get_bindings: * @query_results: #rasqal_query_results query_results * @names: pointer to an array of binding names (or NULL) * @values: pointer to an array of binding value #rasqal_literal (or NULL) * * Get all binding names, values for current result. * * If names is not NULL, it is set to the address of a shared array * of names of the bindings (an output parameter). These names * are shared and must not be freed by the caller * * If values is not NULL, it is set to the address of a shared array * of #rasqal_literal* binding values. These values are shaerd * and must not be freed by the caller. * * Return value: non-0 if the assignment failed **/ int rasqal_query_results_get_bindings(rasqal_query_results* query_results, const unsigned char ***names, rasqal_literal ***values) { rasqal_query* query; if(!query_results) return 1; if(!rasqal_query_results_is_bindings(query_results)) return 1; query=query_results->query; if(names) *names=query->variable_names; if(values) *values=rasqal_engine_get_results_values(query_results); return 0; } /** * rasqal_query_results_get_binding_value: * @query_results: #rasqal_query_results query_results * @offset: offset of binding name into array of known names * * Get one binding value for the current result. * * Return value: a pointer to a shared #rasqal_literal binding value or NULL on failure **/ rasqal_literal* rasqal_query_results_get_binding_value(rasqal_query_results* query_results, int offset) { rasqal_query* query; if(!query_results) return NULL; if(!rasqal_query_results_is_bindings(query_results)) return NULL; query=query_results->query; if(offset < 0 || offset > query->select_variables_count-1) return NULL; return rasqal_engine_get_result_value(query_results, offset); } /** * rasqal_query_results_get_binding_name: * @query_results: #rasqal_query_results query_results * @offset: offset of binding name into array of known names * * Get binding name for the current result. * * Return value: a pointer to a shared copy of the binding name or NULL on failure **/ const unsigned char* rasqal_query_results_get_binding_name(rasqal_query_results* query_results, int offset) { rasqal_query* query; if(!query_results) return NULL; if(!rasqal_query_results_is_bindings(query_results)) return NULL; query=query_results->query; if(offset < 0 || offset > query->select_variables_count-1) return NULL; return query->variables[offset]->name; } /** * rasqal_query_results_get_binding_value_by_name: * @query_results: #rasqal_query_results query_results * @name: variable name * * Get one binding value for a given name in the current result. * * Return value: a pointer to a shared #rasqal_literal binding value or NULL on failure **/ rasqal_literal* rasqal_query_results_get_binding_value_by_name(rasqal_query_results* query_results, const unsigned char *name) { int offset= -1; int i; rasqal_query* query; rasqal_literal* value=NULL; if(!query_results) return NULL; if(!rasqal_query_results_is_bindings(query_results)) return NULL; query=query_results->query; for(i=0; i< query->select_variables_count; i++) { if(!strcmp((const char*)name, (const char*)query->variables[i]->name)) { offset=i; break; } } if(offset < 0) return NULL; value=rasqal_engine_get_result_value(query_results, offset); return value; } /** * rasqal_query_results_get_bindings_count: * @query_results: #rasqal_query_results query_results * * Get the number of bound variables in the result. * * Return value: <0 if failed or results exhausted **/ int rasqal_query_results_get_bindings_count(rasqal_query_results* query_results) { if(!query_results || query_results->failed) return -1; if(!rasqal_query_results_is_bindings(query_results)) return -1; return query_results->query->select_variables_count; } /** * rasqal_query_results_get_triple: * @query_results: #rasqal_query_results query_results * * Get the current triple in the result. * * The return value is a shared #raptor_statement. * * Return value: #raptor_statement or NULL if failed or results exhausted **/ raptor_statement* rasqal_query_results_get_triple(rasqal_query_results* query_results) { rasqal_query* query; int rc; rasqal_triple *t; rasqal_literal *s, *p, *o; raptor_statement *rs; int skipped; if(!query_results || query_results->failed || query_results->finished) return NULL; if(!rasqal_query_results_is_graph(query_results)) return NULL; query=query_results->query; if(query->verb == RASQAL_QUERY_VERB_DESCRIBE) return NULL; skipped=0; while(1) { if(skipped || ((query_results->current_triple_result < 0)|| query_results->current_triple_result >= raptor_sequence_size(query->constructs))) { /* rc<0 error rc=0 end of results, rc>0 got a result */ rc=rasqal_engine_get_next_result(query_results); if(rc < 1) query_results->finished=1; if(rc < 0) query_results->failed=1; if(query_results->finished || query_results->failed) { rs=NULL; break; } query_results->current_triple_result=0; skipped=0; } t=(rasqal_triple*)raptor_sequence_get_at(query->constructs, query_results->current_triple_result); rs=&query_results->result_triple; s=rasqal_literal_as_node(t->subject); if(!s) { rasqal_query_warning(query, "Triple with unbound subject skipped"); skipped=1; continue; } switch(s->type) { case RASQAL_LITERAL_URI: rs->subject=s->value.uri; rs->subject_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; break; case RASQAL_LITERAL_BLANK: s->string=rasqal_prefix_id(query_results->result_count, (unsigned char*)s->string); rs->subject=s->string; rs->subject_type=RAPTOR_IDENTIFIER_TYPE_ANONYMOUS; break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_STRING: /* string [literal] subjects are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: /* case RASQAL_LITERAL_STRING: */ rasqal_query_warning(query, "Triple with non-URI/blank node subject skipped"); skipped=1; break; } if(skipped) { if(s) rasqal_free_literal(s); continue; } p=rasqal_literal_as_node(t->predicate); if(!p) { rasqal_query_warning(query, "Triple with unbound predicate skipped"); rasqal_free_literal(s); skipped=1; continue; } switch(p->type) { case RASQAL_LITERAL_URI: rs->predicate=p->value.uri; rs->predicate_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_BLANK: case RASQAL_LITERAL_STRING: /* blank node or string [literal] predicates are not RDF */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_warning(query, "Triple with non-URI predicate skipped"); skipped=1; break; } if(skipped) { rasqal_free_literal(s); if(p) rasqal_free_literal(p); continue; } o=rasqal_literal_as_node(t->object); if(!o) { rasqal_query_warning(query, "Triple with unbound object skipped"); rasqal_free_literal(s); rasqal_free_literal(p); skipped=1; continue; } switch(o->type) { case RASQAL_LITERAL_URI: rs->object=o->value.uri; rs->object_type=RAPTOR_IDENTIFIER_TYPE_RESOURCE; break; case RASQAL_LITERAL_BLANK: o->string=rasqal_prefix_id(query_results->result_count, (unsigned char*)o->string); rs->object=o->string; rs->object_type=RAPTOR_IDENTIFIER_TYPE_ANONYMOUS; break; case RASQAL_LITERAL_STRING: rs->object=o->string; rs->object_literal_language=(const unsigned char*)o->language; rs->object_literal_datatype=o->datatype; rs->object_type=RAPTOR_IDENTIFIER_TYPE_LITERAL; break; case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: /* QNames should be gone by the time expression eval happens * Everything else is removed by rasqal_literal_as_node() above. */ case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_warning(query, "Triple with unknown object skipped"); skipped=1; break; } if(skipped) { rasqal_free_literal(s); rasqal_free_literal(p); if(o) rasqal_free_literal(o); continue; } /* for saving s, p, o for later disposal */ query_results->triple=rasqal_new_triple(s, p, o); /* got triple, return it */ break; } return rs; } /** * rasqal_query_results_next_triple: * @query_results: #rasqal_query_results query_results * * Move to the next triple result. * * Return value: non-0 if failed or results exhausted **/ int rasqal_query_results_next_triple(rasqal_query_results* query_results) { rasqal_query* query; int rc; if(!query_results || query_results->failed || query_results->finished) return 1; if(!rasqal_query_results_is_graph(query_results)) return 1; query=query_results->query; if(query->verb == RASQAL_QUERY_VERB_DESCRIBE) return 1; if(query_results->triple) { rasqal_free_triple(query_results->triple); query_results->triple=NULL; } if(++query_results->current_triple_result >= raptor_sequence_size(query->constructs)) { /* rc<0 error rc=0 end of results, rc>0 got a result */ rc=rasqal_engine_get_next_result(query_results); if(rc < 1) query_results->finished=1; if(rc < 0) query_results->failed=1; if(query_results->finished || query_results->failed) return 1; query_results->current_triple_result=0; } return 0; } /** * rasqal_query_results_get_boolean: * @query_results: #rasqal_query_results query_results * * Get boolean query result. * * The return value is only meaningful if this is a boolean * query result - see rasqal_query_results_is_boolean() * * Return value: boolean query result - >0 is true, 0 is false, <0 on error or finished */ int rasqal_query_results_get_boolean(rasqal_query_results* query_results) { int rc; if(!query_results || query_results->failed || query_results->finished) return -1; if(!rasqal_query_results_is_boolean(query_results)) return -1; if(query_results->ask_result >= 0) return query_results->ask_result; /* rc<0 error rc=0 end of results, rc>0 got a result */ rc=rasqal_engine_get_next_result(query_results); if(rc < 1) { /* error or end of results */ query_results->finished= 1; query_results->ask_result= 0; /* false */ } if(rc < 0) { /* error */ query_results->failed= 1; query_results->ask_result= -1; /* error */ } if(rc > 0) { /* ok */ query_results->ask_result= 1; /* true */ } return query_results->ask_result; } /** * rasqal_query_results_formats_enumerate: * @counter: index into the list of query result syntaxes * @name: pointer to store the name of the query result syntax (or NULL) * @label: pointer to store query result syntax readable label (or NULL) * @uri_string: pointer to store query result syntax URI string (or NULL) * * Get information on query result syntaxes. * * The current list of format names/URI is given below however * the results of this function will always return the latest. * * SPARQL XML Results 2006-01-25 (default format when @counter is 0) * name 'xml' with * URIs http://www.w3.org/TR/2006/WD-rdf-sparql-XMLres-20060125/ or * http://www.w3.org/2005/sparql-results# * * JSON name 'json' and * URI http://www.w3.org/2001/sw/DataAccess/json-sparql/ * * Older formats: * * Name 'xml-v2' with * URIs http://www.w3.org/TR/2005/WD-rdf-sparql-XMLres-20050527/ or * http://www.w3.org/2001/sw/DataAccess/rf1/result2 * * Name 'xml-v1' with * URIs http://www.w3.org/TR/2004/WD-rdf-sparql-XMLres-20041221/ or * http://www.w3.org/2001/sw/DataAccess/rf1/result * * If the writing succeeds, the query results will be exhausted. * * Return value: non 0 on failure of if counter is out of range **/ int rasqal_query_results_formats_enumerate(const unsigned int counter, const char **name, const char **label, const unsigned char **uri_string) { rasqal_query_results_format_factory *factory; int i; unsigned int real_counter; real_counter=0; for(i=0; 1; i++) { factory=(rasqal_query_results_format_factory*)raptor_sequence_get_at(query_results_formats, i); if(!factory) break; if(factory->name) { if(real_counter == counter) break; real_counter++; } } if(!factory) return 1; if(name) *name=factory->name; if(label) *label=factory->label; if(uri_string) *uri_string=factory->uri_string; return 0; } static rasqal_query_results_format_factory* rasqal_get_query_results_formatter_factory(const char *name, raptor_uri* uri) { int i; rasqal_query_results_format_factory* factory=NULL; for(i=0; 1; i++) { factory=(rasqal_query_results_format_factory*)raptor_sequence_get_at(query_results_formats, i); if(!factory) break; if(!name && !uri) /* the default is the first registered format */ break; if(name && factory->name && !strcmp(factory->name, (const char*)name)) return factory; if(uri && factory->uri_string && !strcmp((const char*)raptor_uri_as_string(uri), (const char*)factory->uri_string)) break; } return factory; } /** * rasqal_new_query_results_formatter: * @name: the query results format name (or NULL) * @uri: #raptor_uri query results format uri (or NULL) * * Constructor - create a new rasqal_query_results_formatter object. * * A query results format can be named or identified by a URI, both * of which are optional. The default query results format will be used * if both are NULL. rasqal_query_results_formats_enumerate() returns * information on the known query results names, labels and URIs. * * Return value: a new #rasqal_query_results_formatter object or NULL on failure */ rasqal_query_results_formatter* rasqal_new_query_results_formatter(const char *name, raptor_uri* uri) { rasqal_query_results_format_factory* factory; rasqal_query_results_formatter* formatter; factory=rasqal_get_query_results_formatter_factory(name, uri); if(!factory) return NULL; formatter=(rasqal_query_results_formatter*)RASQAL_CALLOC(rasqal_query_results_formatter, 1, sizeof(rasqal_query_results_formatter)); formatter->factory=factory; return formatter; } /** * rasqal_free_query_results_formatter: * @formatter: #rasqal_query_results_formatter object * * Destructor - destroy a #rasqal_query_results_formatter object. **/ void rasqal_free_query_results_formatter(rasqal_query_results_formatter* formatter) { RASQAL_FREE(rasqal_query_results_formatter, formatter); } /** * rasqal_query_results_formatter_write: * @iostr: #raptor_iostream to write the query to * @formatter: #rasqal_query_results_formatter object * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the output format * * Write the query results using the given formatter to an iostream * * See rasqal_query_results_formats_enumerate() to get the * list of syntax URIs and their description. * * Return value: non-0 on failure **/ int rasqal_query_results_formatter_write(raptor_iostream *iostr, rasqal_query_results_formatter* formatter, rasqal_query_results* results, raptor_uri *base_uri) { return formatter->factory->writer(iostr, results, base_uri); } /** * rasqal_query_results_write: * @iostr: #raptor_iostream to write the query to * @results: #rasqal_query_results query results format * @format_uri: #raptor_uri describing the format to write (or NULL for default) * @base_uri: #raptor_uri base URI of the output format * * Write the query results to an iostream in a format. * * This uses the #rasqal_query_results_formatter class * and the rasqal_query_results_formatter_write() method * to perform the formatting. See * rasqal_query_results_formats_enumerate() * for obtaining the supported format URIs at run time. * * Return value: non-0 on failure **/ int rasqal_query_results_write(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *format_uri, raptor_uri *base_uri) { rasqal_query_results_formatter *formatter; int status; if(!results || results->failed || results->finished) return 1; formatter=rasqal_new_query_results_formatter(NULL, format_uri); if(!formatter) return 1; status=rasqal_query_results_formatter_write(iostr, formatter, results, base_uri); rasqal_free_query_results_formatter(formatter); return status; } /* * rasqal_query_results_write_xml_20041221: * @iostr: #raptor_iostream to write the query to * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the output format * * Write the 2004-12-21 XML query results format to an iostream in a * format - INTERNAL. * * If the writing succeeds, the query results will be exhausted. * * Return value: non-0 on failure **/ static int rasqal_query_results_write_xml_20041221(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri) { rasqal_query* query=results->query; raptor_uri_handler *uri_handler; void *uri_context; raptor_xml_writer* xml_writer; raptor_namespace *res_ns; raptor_namespace_stack *nstack; raptor_qname* sparql_qname; raptor_xml_element *sparql_element; raptor_qname* results_qname; raptor_xml_element *results_element; raptor_qname* result_qname; raptor_xml_element *result_element; raptor_qname* qname1; raptor_xml_element *element1; raptor_qname **attrs; int i; raptor_uri* base_uri_copy=NULL; if(!rasqal_query_results_is_bindings(results)) { rasqal_query_error(query, "Can only write XML format 2004-11-21 for variable binding results"); return 1; } raptor_uri_get_handler(&uri_handler, &uri_context); nstack=raptor_new_namespaces(uri_handler, uri_context, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); xml_writer=raptor_new_xml_writer(nstack, uri_handler, uri_context, iostr, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); if(!xml_writer) return 1; res_ns=raptor_new_namespace(nstack, NULL, (const unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result", 0); sparql_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"sparql", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; sparql_element=raptor_new_xml_element(sparql_qname, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* */ qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"head", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); for(i=0; 1; i++) { const unsigned char *name; raptor_qname* variable_qname; raptor_xml_element *variable_element; name=rasqal_query_results_get_binding_name(results, i); if(!name) break; /* */ variable_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"variable", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; variable_element=raptor_new_xml_element(variable_qname, NULL, base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"name", (const unsigned char*)name); /* attribute value */ raptor_xml_element_set_attributes(variable_element, attrs, 1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_empty_element(xml_writer, variable_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(variable_element); } /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(element1); /* */ results_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"results", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; results_element=raptor_new_xml_element(results_qname, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* declare result element for later multiple use */ result_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"result", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; result_element=raptor_new_xml_element(result_qname, NULL, /* language */ base_uri_copy); while(!rasqal_query_results_finished(results)) { /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_start_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); for(i=0; itype) { case RASQAL_LITERAL_URI: attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"uri", (const unsigned char*)raptor_uri_as_string(l->value.uri)); raptor_xml_element_set_attributes(element1, attrs, 1); raptor_xml_writer_empty_element(xml_writer, element1); break; case RASQAL_LITERAL_BLANK: attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"bnodeid", l->string); raptor_xml_element_set_attributes(element1, attrs, 1); raptor_xml_writer_empty_element(xml_writer, element1); break; case RASQAL_LITERAL_STRING: if(l->language || l->datatype) { attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); if(l->language) attrs[0]=raptor_new_qname(nstack, (const unsigned char*)"xml:lang", (const unsigned char*)l->language, (raptor_simple_message_handler)rasqal_query_simple_error, query); else attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"datatype", (const unsigned char*)raptor_uri_as_string(l->datatype)); raptor_xml_element_set_attributes(element1, attrs, 1); } raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata_counted(xml_writer, (const unsigned char*)l->string, l->string_len); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_error(query, "Cannot turn literal type %d into XML", l->type); } raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(element1); } raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_end_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); rasqal_query_results_next(results); } raptor_free_xml_element(result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(results_element); raptor_xml_writer_end_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(sparql_element); raptor_free_xml_writer(xml_writer); raptor_free_namespace(res_ns); raptor_free_namespaces(nstack); return 0; } /* * rasqal_query_results_write_xml_result2: * @iostr: #raptor_iostream to write the query to * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the output format * * Write the second version of the XML query results format to an * iostream in a format - INTERNAL. * * If the writing succeeds, the query results will be exhausted. * * Return value: non-0 on failure **/ static int rasqal_query_results_write_xml_result2(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri) { rasqal_query* query=results->query; raptor_uri_handler *uri_handler; void *uri_context; raptor_xml_writer* xml_writer; raptor_namespace *res_ns; raptor_namespace_stack *nstack; raptor_qname* sparql_qname; raptor_xml_element *sparql_element; raptor_qname* results_qname; raptor_xml_element *results_element; raptor_qname* result_qname; raptor_xml_element *result_element; raptor_qname* qname1; raptor_xml_element *element1; raptor_qname **attrs; int i; raptor_uri* base_uri_copy=NULL; if(!rasqal_query_results_is_bindings(results) && !rasqal_query_results_is_boolean(results)) { rasqal_query_error(query, "Can only write XML format v2 for variable binding and boolean results"); return 1; } raptor_uri_get_handler(&uri_handler, &uri_context); nstack=raptor_new_namespaces(uri_handler, uri_context, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); xml_writer=raptor_new_xml_writer(nstack, uri_handler, uri_context, iostr, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); if(!xml_writer) return 1; res_ns=raptor_new_namespace(nstack, NULL, (const unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result2", 0); sparql_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"sparql", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; sparql_element=raptor_new_xml_element(sparql_qname, NULL, /* language */ base_uri_copy); if(rasqal_query_results_is_bindings(results)) { raptor_namespace* xsi_ns; raptor_namespace* xs_ns; xsi_ns=raptor_new_namespace(nstack, (const unsigned char*)"xsi", (const unsigned char*)"http://www.w3.org/2001/XMLSchema-instance", 0); raptor_xml_element_declare_namespace(sparql_element, xsi_ns); xs_ns=raptor_new_namespace(nstack, (const unsigned char*)"xs", (const unsigned char*)"http://www.w3.org/2001/XMLSchema", 0); raptor_xml_element_declare_namespace(sparql_element, xs_ns); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(xsi_ns, (const unsigned char*)"schemaLocation", (const unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd"); raptor_xml_element_set_attributes(sparql_element, attrs, 1); } raptor_xml_writer_start_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* */ qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"head", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* At present for boolean results has no content */ if(rasqal_query_results_is_bindings(results)) { for(i=0; 1; i++) { const unsigned char *name; raptor_qname* variable_qname; raptor_xml_element *variable_element; name=rasqal_query_results_get_binding_name(results, i); if(!name) break; /* */ variable_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"variable", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; variable_element=raptor_new_xml_element(variable_qname, NULL, base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"name", (const unsigned char*)name); /* attribute value */ raptor_xml_element_set_attributes(variable_element, attrs, 1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_empty_element(xml_writer, variable_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(variable_element); } } /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(element1); /* */ results_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"results", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; results_element=raptor_new_xml_element(results_qname, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* Boolean Results */ if(rasqal_query_results_is_boolean(results)) { result_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"boolean", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; result_element=raptor_new_xml_element(result_qname, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_start_element(xml_writer, result_element); if(rasqal_query_results_get_boolean(results)) raptor_xml_writer_raw(xml_writer, RASQAL_XSD_BOOLEAN_TRUE); else raptor_xml_writer_raw(xml_writer, RASQAL_XSD_BOOLEAN_FALSE); raptor_xml_writer_end_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); goto resultsdone; } /* Variable Binding Results */ /* declare result element for later multiple use */ result_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"result", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; result_element=raptor_new_xml_element(result_qname, NULL, /* language */ base_uri_copy); while(!rasqal_query_results_finished(results)) { /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_start_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); for(i=0; i */ binding_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"binding", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; binding_element=raptor_new_xml_element(binding_qname, NULL, /* language */ base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"name", name); raptor_xml_element_set_attributes(binding_element, attrs, 1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 6); raptor_xml_writer_start_element(xml_writer, binding_element); if(!l) { qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"unbound", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_empty_element(xml_writer, element1); } else switch(l->type) { case RASQAL_LITERAL_URI: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"uri", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)raptor_uri_as_string(l->value.uri)); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_BLANK: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"bnode", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)l->string); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_STRING: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"literal", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); if(l->language || l->datatype) { attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); if(l->language) attrs[0]=raptor_new_qname(nstack, (const unsigned char*)"xml:lang", (const unsigned char*)l->language, (raptor_simple_message_handler)rasqal_query_simple_error, query); else attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"datatype", (const unsigned char*)raptor_uri_as_string(l->datatype)); raptor_xml_element_set_attributes(element1, attrs, 1); } raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata_counted(xml_writer, (const unsigned char*)l->string, l->string_len); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_error(query, "Cannot turn literal type %d into XML", l->type); } raptor_free_xml_element(element1); /* */ raptor_xml_writer_end_element(xml_writer, binding_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(binding_element); } raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_end_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); rasqal_query_results_next(results); } resultsdone: raptor_free_xml_element(result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(results_element); raptor_xml_writer_end_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(sparql_element); raptor_free_xml_writer(xml_writer); raptor_free_namespace(res_ns); raptor_free_namespaces(nstack); return 0; } /* * rasqal_query_results_write_xml_result3: * @iostr: #raptor_iostream to write the query to * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the output format * * Write the third version of the XML query results format to an * iostream in a format - INTERNAL. * * If the writing succeeds, the query results will be exhausted. * * Return value: non-0 on failure **/ static int rasqal_query_results_write_xml_result3(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri) { rasqal_query* query=results->query; raptor_uri_handler *uri_handler; void *uri_context; raptor_xml_writer* xml_writer; raptor_namespace *res_ns; raptor_namespace_stack *nstack; raptor_qname* sparql_qname; raptor_xml_element *sparql_element; raptor_qname* results_qname; raptor_xml_element *results_element; raptor_qname* result_qname; raptor_xml_element *result_element; raptor_qname* qname1; raptor_xml_element *element1; raptor_qname **attrs; int i; raptor_uri* base_uri_copy=NULL; if(!rasqal_query_results_is_bindings(results) && !rasqal_query_results_is_boolean(results)) { rasqal_query_error(query, "Can only write XML format v3 for variable binding and boolean results"); return 1; } raptor_uri_get_handler(&uri_handler, &uri_context); nstack=raptor_new_namespaces(uri_handler, uri_context, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); xml_writer=raptor_new_xml_writer(nstack, uri_handler, uri_context, iostr, (raptor_simple_message_handler)rasqal_query_simple_error, query, 1); if(!xml_writer) return 1; res_ns=raptor_new_namespace(nstack, NULL, (const unsigned char*)"http://www.w3.org/2005/sparql-results#", 0); sparql_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"sparql", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; sparql_element=raptor_new_xml_element(sparql_qname, NULL, /* language */ base_uri_copy); if(rasqal_query_results_is_bindings(results)) { /* FIXME - consider when to write the XSD. Need the XSD URI too. */ #if 0 raptor_namespace* xsi_ns; xsi_ns=raptor_new_namespace(nstack, (const unsigned char*)"xsi", (const unsigned char*)"http://www.w3.org/2001/XMLSchema-instance", 0); raptor_xml_element_declare_namespace(sparql_element, xsi_ns); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(xsi_ns, (const unsigned char*)"schemaLocation", (const unsigned char*)"http://www.w3.org/2001/sw/DataAccess/rf1/result2.xsd"); raptor_xml_element_set_attributes(sparql_element, attrs, 1); #endif } raptor_xml_writer_start_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* */ qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"head", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); if(rasqal_query_results_is_bindings(results)) { for(i=0; 1; i++) { const unsigned char *name; raptor_qname* variable_qname; raptor_xml_element *variable_element; name=rasqal_query_results_get_binding_name(results, i); if(!name) break; /* */ variable_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"variable", NULL); /* no attribute value - element */ base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; variable_element=raptor_new_xml_element(variable_qname, NULL, base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"name", (const unsigned char*)name); /* attribute value */ raptor_xml_element_set_attributes(variable_element, attrs, 1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_empty_element(xml_writer, variable_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(variable_element); } } /* FIXME - could add inside */ /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, element1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(element1); /* Boolean Results */ if(rasqal_query_results_is_boolean(results)) { result_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"boolean", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; result_element=raptor_new_xml_element(result_qname, NULL, /* language */ base_uri_copy); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, result_element); if(rasqal_query_results_get_boolean(results)) raptor_xml_writer_raw(xml_writer, RASQAL_XSD_BOOLEAN_TRUE); else raptor_xml_writer_raw(xml_writer, RASQAL_XSD_BOOLEAN_FALSE); raptor_xml_writer_end_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); goto results3done; } /* Variable Binding Results */ /* */ results_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"results", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; results_element=raptor_new_xml_element(results_qname, NULL, /* language */ base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(2*sizeof(raptor_qname*)); i=(rasqal_query_get_order_condition(query, 0) != NULL); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"ordered", i ? RASQAL_XSD_BOOLEAN_TRUE : RASQAL_XSD_BOOLEAN_FALSE); i=rasqal_query_get_distinct(query); attrs[1]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"distinct", i ? RASQAL_XSD_BOOLEAN_TRUE : RASQAL_XSD_BOOLEAN_FALSE); raptor_xml_element_set_attributes(results_element, attrs, 2); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_start_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); /* declare result element for later multiple use */ result_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"result", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; result_element=raptor_new_xml_element(result_qname, NULL, /* language */ base_uri_copy); while(!rasqal_query_results_finished(results)) { /* */ raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_start_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); for(i=0; i */ binding_qname=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"binding", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; binding_element=raptor_new_xml_element(binding_qname, NULL, /* language */ base_uri_copy); attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"name", name); raptor_xml_element_set_attributes(binding_element, attrs, 1); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 6); raptor_xml_writer_start_element(xml_writer, binding_element); if(!l) { qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"unbound", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_empty_element(xml_writer, element1); } else switch(l->type) { case RASQAL_LITERAL_URI: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"uri", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)raptor_uri_as_string(l->value.uri)); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_BLANK: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"bnode", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)l->string); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_STRING: qname1=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"literal", NULL); base_uri_copy=base_uri ? raptor_uri_copy(base_uri) : NULL; element1=raptor_new_xml_element(qname1, NULL, /* language */ base_uri_copy); if(l->language || l->datatype) { attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*)); if(l->language) attrs[0]=raptor_new_qname(nstack, (const unsigned char*)"xml:lang", (const unsigned char*)l->language, (raptor_simple_message_handler)rasqal_query_simple_error, query); else attrs[0]=raptor_new_qname_from_namespace_local_name(res_ns, (const unsigned char*)"datatype", (const unsigned char*)raptor_uri_as_string(l->datatype)); raptor_xml_element_set_attributes(element1, attrs, 1); } raptor_xml_writer_start_element(xml_writer, element1); raptor_xml_writer_cdata_counted(xml_writer, (const unsigned char*)l->string, l->string_len); raptor_xml_writer_end_element(xml_writer, element1); break; case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_error(query, "Cannot turn literal type %d into XML", l->type); } raptor_free_xml_element(element1); /* */ raptor_xml_writer_end_element(xml_writer, binding_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(binding_element); } raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 4); raptor_xml_writer_end_element(xml_writer, result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); rasqal_query_results_next(results); } raptor_free_xml_element(result_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)" ", 2); raptor_xml_writer_end_element(xml_writer, results_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(results_element); results3done: raptor_xml_writer_end_element(xml_writer, sparql_element); raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); raptor_free_xml_element(sparql_element); raptor_free_xml_writer(xml_writer); raptor_free_namespace(res_ns); raptor_free_namespaces(nstack); return 0; } static void raptor_iostream_write_json_boolean(raptor_iostream* iostr, const char* name, int bool) { raptor_iostream_write_string(iostr, name); raptor_iostream_write_counted_string(iostr, "\" : ",4); if(bool) raptor_iostream_write_counted_string(iostr, "true", 4); else raptor_iostream_write_counted_string(iostr, "false", 5); } /* * rasqal_query_results_write_json1: * @iostr: #raptor_iostream to write the query to * @results: #rasqal_query_results query results format * @base_uri: #raptor_uri base URI of the output format * * Write a JSON version of the query results format to an * iostream in a format - INTERNAL. * * If the writing succeeds, the query results will be exhausted. * * Return value: non-0 on failure **/ static int rasqal_query_results_write_json1(raptor_iostream *iostr, rasqal_query_results* results, raptor_uri *base_uri) { rasqal_query* query=results->query; int i; int row_comma; int column_comma=0; if(!rasqal_query_results_is_bindings(results) && !rasqal_query_results_is_boolean(results)) { rasqal_query_error(query, "Can only write JSON format for variable binding and boolean results"); return 1; } raptor_iostream_write_counted_string(iostr, "{\n", 2); /* Header */ raptor_iostream_write_counted_string(iostr, " \"head\": {\n", 12); if(rasqal_query_results_is_bindings(results)) { raptor_iostream_write_counted_string(iostr, " \"vars\": [ ", 14); for(i=0; 1; i++) { const unsigned char *name; name=rasqal_query_results_get_binding_name(results, i); if(!name) break; /* 'x', */ if(i > 0) raptor_iostream_write_counted_string(iostr, ", ", 2); raptor_iostream_write_byte(iostr, '\"'); raptor_iostream_write_string(iostr, name); raptor_iostream_write_byte(iostr, '\"'); } raptor_iostream_write_counted_string(iostr, " ]\n", 3); } /* FIXME - could add link inside 'head': */ /* End Header */ raptor_iostream_write_counted_string(iostr, " },\n", 5); /* Boolean Results */ if(rasqal_query_results_is_boolean(results)) { raptor_iostream_write_counted_string(iostr, " ", 2); raptor_iostream_write_json_boolean(iostr, "boolean", rasqal_query_results_get_boolean(results)); goto results3done; } /* Variable Binding Results */ raptor_iostream_write_counted_string(iostr, " \"results\": {\n", 15); raptor_iostream_write_counted_string(iostr, " \"", 5); raptor_iostream_write_json_boolean(iostr, "ordered", (rasqal_query_get_order_condition(query, 0) != NULL)); raptor_iostream_write_counted_string(iostr, ",\n", 2); raptor_iostream_write_counted_string(iostr, " \"", 5); raptor_iostream_write_json_boolean(iostr, "distinct", rasqal_query_get_distinct(query)); raptor_iostream_write_counted_string(iostr, ",\n", 2); raptor_iostream_write_counted_string(iostr, " \"bindings\" : [\n", 19); row_comma=0; while(!rasqal_query_results_finished(results)) { if(row_comma) raptor_iostream_write_counted_string(iostr, ",\n", 2); /* Result row */ raptor_iostream_write_counted_string(iostr, " {\n", 8); column_comma=0; for(i=0; i */ raptor_iostream_write_counted_string(iostr, " \"", 9); raptor_iostream_write_string(iostr, name); raptor_iostream_write_counted_string(iostr, "\" : { ", 6); if(!l) { raptor_iostream_write_string(iostr, "\"type\": \"unbound\", \"value\": null"); } else switch(l->type) { const unsigned char* str; size_t len; case RASQAL_LITERAL_URI: raptor_iostream_write_string(iostr, "\"type\": \"uri\", \"value\": \""); str=(const unsigned char*)raptor_uri_as_counted_string(l->value.uri, &len); raptor_iostream_write_string_ntriples(iostr, str, len, '"'); raptor_iostream_write_byte(iostr, '"'); break; case RASQAL_LITERAL_BLANK: raptor_iostream_write_string(iostr, "\"type\": \"bnode\", \"value\": \""); raptor_iostream_write_string_ntriples(iostr, (const unsigned char*)l->string, l->string_len, '"'); raptor_iostream_write_byte(iostr, '"'); break; case RASQAL_LITERAL_STRING: raptor_iostream_write_string(iostr, "\"type\": \"literal\", \"value\": \""); raptor_iostream_write_string_ntriples(iostr, (const unsigned char*)l->string, l->string_len, '"'); raptor_iostream_write_byte(iostr, '"'); if(l->language) { raptor_iostream_write_string(iostr, ",\n \"xml:lang\" : \""); raptor_iostream_write_string(iostr, (const unsigned char*)l->language); raptor_iostream_write_byte(iostr, '"'); } if(l->datatype) { raptor_iostream_write_string(iostr, ",\n \"datatype\" : \""); str=(const unsigned char*)raptor_uri_as_counted_string(l->datatype, &len); raptor_iostream_write_string_ntriples(iostr, str, len, '"'); raptor_iostream_write_byte(iostr, '"'); } break; case RASQAL_LITERAL_PATTERN: case RASQAL_LITERAL_QNAME: case RASQAL_LITERAL_INTEGER: case RASQAL_LITERAL_BOOLEAN: case RASQAL_LITERAL_DOUBLE: case RASQAL_LITERAL_FLOAT: case RASQAL_LITERAL_VARIABLE: case RASQAL_LITERAL_DECIMAL: case RASQAL_LITERAL_DATETIME: case RASQAL_LITERAL_UNKNOWN: default: rasqal_query_error(query, "Cannot turn literal type %d into XML", l->type); } /* End Binding */ raptor_iostream_write_counted_string(iostr, " }", 2); column_comma=1; } /* End Result Row */ raptor_iostream_write_counted_string(iostr, "\n }", 8); row_comma=1; rasqal_query_results_next(results); } raptor_iostream_write_counted_string(iostr, "\n ]\n }", 10); results3done: /* end sparql */ raptor_iostream_write_counted_string(iostr, "\n}\n", 3); return 0; }