Exemplo n.º 1
0
static void
print_boolean_result_simple(rasqal_query_results *results,
                            FILE* output, int quiet)
{
    fprintf(stderr, "%s: Query has a boolean result: %s\n", program,
            rasqal_query_results_get_boolean(results) ? "true" : "false");
}
Exemplo n.º 2
0
static int
librdf_query_rasqal_results_get_boolean(librdf_query_results* query_results)
{
  librdf_query *query=query_results->query;
  librdf_query_rasqal_context *context=(librdf_query_rasqal_context*)query->context;

  if(!context->results)
    return -1;
  
  return rasqal_query_results_get_boolean(context->results);
}
Exemplo n.º 3
0
/*
 * 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(rasqal_query_results_formatter* formatter,
                                 raptor_iostream *iostr,
                                 rasqal_query_results* results,
                                 raptor_uri *base_uri)
{
  rasqal_world* world = rasqal_query_results_get_world(results);
  rasqal_query* query = rasqal_query_results_get_query(results);
  int i;
  int row_comma;
  int column_comma = 0;
  rasqal_query_results_type type;

  type = rasqal_query_results_get_type(results);

  if(type != RASQAL_QUERY_RESULTS_BINDINGS &&
     type != RASQAL_QUERY_RESULTS_BOOLEAN) {
    rasqal_log_error_simple(query->world, RAPTOR_LOG_LEVEL_ERROR,
                            &query->locator,
                            "Cannot write JSON for %s query result format",
                            rasqal_query_results_type_label(type));
    return 1;
  }

  raptor_iostream_counted_string_write("{\n", 2, iostr);
  
  /* Header */
  raptor_iostream_counted_string_write("  \"head\": {\n", 12, iostr);
  
  if(rasqal_query_results_is_bindings(results)) {
    raptor_iostream_counted_string_write("    \"vars\": [ ", 14, iostr);
    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_counted_string_write(", ", 2, iostr);
      raptor_iostream_write_byte('\"', iostr);
      raptor_iostream_string_write(name, iostr);
      raptor_iostream_write_byte('\"', iostr);
    }
    raptor_iostream_counted_string_write(" ]\n", 3, iostr);
  }

  /* FIXME - could add link inside 'head': */
    
  /*   End Header */
  raptor_iostream_counted_string_write("  },\n", 5, iostr);


  /* Boolean Results */
  if(rasqal_query_results_is_boolean(results)) {
    raptor_iostream_counted_string_write("  ", 2, iostr);
    rasqal_iostream_write_json_boolean(iostr, "boolean", 
                                       rasqal_query_results_get_boolean(results));
    goto results3done;
  }

  /* Variable Binding Results */
  raptor_iostream_counted_string_write("  \"results\": {\n", 15, iostr);

  if(query) {
    raptor_iostream_counted_string_write("    ", 4, iostr);
    rasqal_iostream_write_json_boolean(iostr, "ordered", 
                                       (rasqal_query_get_order_condition(query, 0) != NULL));
    raptor_iostream_counted_string_write(",\n", 2, iostr);

    raptor_iostream_counted_string_write("    ", 4, iostr);
    rasqal_iostream_write_json_boolean(iostr, "distinct", 
                                       rasqal_query_get_distinct(query));
    raptor_iostream_counted_string_write(",\n", 2, iostr);
  }
  
  raptor_iostream_counted_string_write("    \"bindings\" : [\n", 19, iostr);

  row_comma = 0;
  while(!rasqal_query_results_finished(results)) {
    if(row_comma)
      raptor_iostream_counted_string_write(",\n", 2, iostr);

    /* Result row */
    raptor_iostream_counted_string_write("      {\n", 8, iostr);

    column_comma = 0;
    for(i = 0; i<rasqal_query_results_get_bindings_count(results); i++) {
      const unsigned char *name = rasqal_query_results_get_binding_name(results, i);
      rasqal_literal *l = rasqal_query_results_get_binding_value(results, i);

      if(column_comma)
        raptor_iostream_counted_string_write(",\n", 2, iostr);

      /*       <binding> */
      raptor_iostream_counted_string_write("        \"", 9, iostr);
      raptor_iostream_string_write(name, iostr);
      raptor_iostream_counted_string_write("\" : { ", 6, iostr);

      if(!l) {
        raptor_iostream_string_write("\"type\": \"unbound\", \"value\": null", iostr);
      } else {
        const unsigned char* str;
        size_t len;

        switch(l->type) {
          case RASQAL_LITERAL_URI:
            raptor_iostream_string_write("\"type\": \"uri\", \"value\": \"", iostr);
            str = RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_counted_string(l->value.uri, &len));
            raptor_string_ntriples_write(str, len, '"', iostr);
            raptor_iostream_write_byte('"', iostr);
            break;

          case RASQAL_LITERAL_BLANK:
            raptor_iostream_string_write("\"type\": \"bnode\", \"value\": \"", iostr);
            raptor_string_ntriples_write(l->string, l->string_len, '"', iostr);
            raptor_iostream_write_byte('"', iostr);
            break;

          case RASQAL_LITERAL_STRING:
            raptor_iostream_string_write("\"type\": \"literal\", \"value\": \"", iostr);
            raptor_string_ntriples_write(l->string, l->string_len, '"', iostr);
            raptor_iostream_write_byte('"', iostr);

            if(l->language) {
              raptor_iostream_string_write(",\n      \"xml:lang\" : \"", iostr);
              raptor_iostream_string_write(RASQAL_GOOD_CAST(const unsigned char*, l->language), iostr);
              raptor_iostream_write_byte('"', iostr);
            }

            if(l->datatype) {
              raptor_iostream_string_write(",\n      \"datatype\" : \"", iostr);
              str = RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_counted_string(l->datatype, &len));
              raptor_string_ntriples_write(str, len, '"', iostr);
              raptor_iostream_write_byte('"', iostr);
            }

            break;

          case RASQAL_LITERAL_PATTERN:
          case RASQAL_LITERAL_QNAME:
          case RASQAL_LITERAL_INTEGER:
          case RASQAL_LITERAL_XSD_STRING:
          case RASQAL_LITERAL_BOOLEAN:
          case RASQAL_LITERAL_DOUBLE:
          case RASQAL_LITERAL_FLOAT:
          case RASQAL_LITERAL_VARIABLE:
          case RASQAL_LITERAL_DECIMAL:
          case RASQAL_LITERAL_DATE:
          case RASQAL_LITERAL_DATETIME:
          case RASQAL_LITERAL_UDT:
          case RASQAL_LITERAL_INTEGER_SUBTYPE:

          case RASQAL_LITERAL_UNKNOWN:
          default:
            rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR, NULL,
                                    "Cannot turn literal type %u into XML",
                                    l->type);
        }
      }

      /* End Binding */
      raptor_iostream_counted_string_write(" }", 2, iostr);
      column_comma = 1;
    }
Exemplo n.º 4
0
int
main(int argc, char *argv[]) 
{ 
  rasqal_world *world;
  raptor_world* raptor_world_ptr = NULL;
  int rc = 0;
  int usage = 0;
  int help = 0;
  const char* query_language = DEFAULT_QUERY_LANGUAGE;
  const char* query_filename = NULL;
  const char* data_format_name = NULL;
  const char* result_filename = NULL;
  const char* result_format_name = NULL;
  unsigned char* query_string = NULL;
  size_t query_len = 0;
  unsigned char *query_base_uri_string = NULL;
  int free_query_base_uri_string = 0;
  raptor_uri* query_base_uri = NULL;
  rasqal_query* rq = NULL;
  rasqal_query_results* results = NULL;
  rasqal_query_results* expected_results = NULL;
  raptor_sequence* data_graphs = NULL;
  raptor_iostream* result_iostr = NULL;
  rasqal_dataset* ds = NULL;
  rasqal_query_results_type results_type;

  /* Set globals */
  if(1) {
    char *p;
    
    program = argv[0];
    if((p = strrchr(program, '/')))
      program = p + 1;
    else if((p = strrchr(program, '\\')))
      program = p + 1;
    argv[0] = program;
  }
  
  world = rasqal_new_world();
  if(!world || rasqal_world_open(world)) {
    fprintf(stderr, "%s: rasqal_world init failed\n", program);
    return(1);
  }
  
  raptor_world_ptr = rasqal_world_get_raptor(world);
  rasqal_world_set_log_handler(world, world, check_query_log_handler);

  /* Option parsing */
  while (!usage && !help)
  {
    int c;
    
#ifdef HAVE_GETOPT_LONG
    int option_index = 0;

    c = getopt_long (argc, argv, GETOPT_STRING, long_options, &option_index);
#else
    c = getopt (argc, argv, GETOPT_STRING);
#endif
    if (c == -1)
      break;

    switch (c) {
      case 0:
      case '?': /* getopt() - unknown option */
        usage = 1;
        break;
        
      case 'd':
        verbose++;
        break;

      case 'F':
        if(optarg) {
          data_format_name = optarg;
        }
        break;
        
      case 'h':
        help = 1;
        break;

      case 'l':
        if(optarg) {
          query_language = optarg;
        }
        break;

      case 'q':
        if(optarg) {
          query_filename = optarg;
        }
        break;

      case 'Q':
        if(optarg) {
          query_base_uri_string = (unsigned char*)optarg;
        }
        break;

      case 'r':
        if(optarg) {
          result_filename = optarg;
        }
        break;
        
      case 'R':
        if(optarg) {
          result_format_name = optarg;
        }
        break;
        
      case 'v':
        fputs(rasqal_version_string, stdout);
        fputc('\n', stdout);
        rasqal_free_world(world);
        exit(0);

      case 'g':
      case 'n':
        if(optarg) {
          rasqal_data_graph *dg = NULL;
          rasqal_data_graph_flags type;

          type = (c == 'n') ? RASQAL_DATA_GRAPH_NAMED : 
                              RASQAL_DATA_GRAPH_BACKGROUND;
          dg = rasqal_cmdline_read_data_graph(world, type, (const char*)optarg,
                                              data_format_name);
          if(!dg) {
            fprintf(stderr, "%s: Failed to create data graph for `%s'\n",
                    program, optarg);
            return(1);
          }
          
          if(!data_graphs) {
            data_graphs = raptor_new_sequence((raptor_data_free_handler)rasqal_free_data_graph,
                                              NULL);

            if(!data_graphs) {
              fprintf(stderr, "%s: Failed to create data graphs sequence\n",
                      program);
              return(1);
            }
          }

          raptor_sequence_push(data_graphs, dg);
        }
        break;

    }
    
  } /* end while option */


  if(!help && !usage) {
    if(optind != argc) {
      fprintf(stderr, "%s: Extra arguments.\n", program);
      usage = 1;
    } else if(!result_filename) {
      usage = 2; /* Title and usage */
    } else if(!query_filename) {
      usage = 2; /* Title and usage */
    }
  }

  
  if(usage) {
    if(usage > 1) {
      fprintf(stderr, title_format_string, rasqal_version_string);
      fputs("Rasqal home page: ", stderr);
      fputs(rasqal_home_url_string, stderr);
      fputc('\n', stderr);
      fputs(rasqal_copyright_string, stderr);
      fputs("\nLicense: ", stderr);
      fputs(rasqal_license_string, stderr);
      fputs("\n\n", stderr);
    }
    fprintf(stderr, "Try `%s " HELP_ARG(h, help) "' for more information.\n",
            program);
    rasqal_free_world(world);

    exit(1);
  }

  if(help) {
    int i;

    printf(title_format_string, rasqal_version_string);
    puts("Run an RDF query and check it against a known result.");
    printf("Usage: %s [OPTIONS] -g DATA -q QUERY-FILE -r RESULT-FILE\n\n", program);

    fputs(rasqal_copyright_string, stdout);
    fputs("\nLicense: ", stdout);
    puts(rasqal_license_string);
    fputs("Rasqal home page: ", stdout);
    puts(rasqal_home_url_string);

    puts("\nNormal operation is to execute the query in the QUERY-FILE and\ncompare to the query results in RESULT-FILE.");
    puts("\nMain options:");
    puts(HELP_TEXT("g URI", "default-graph URI", "Use URI as the default graph in the dataset"));
    puts(HELP_TEXT("l", "language LANGUAGE    ", "Set query language name to one of:"));
    for(i = 0; 1; i++) {
      const raptor_syntax_description* desc;

      desc = rasqal_world_get_query_language_description(world, i);
      if(!desc)
         break;

      printf("    %-15s              %s", desc->names[0], desc->label);
      if(!i)
        puts(" (default)");
      else
        putchar('\n');
    }
    puts(HELP_TEXT("n URI", "named-graph URI  ", "Add named graph URI to dataset"));
    puts(HELP_TEXT("q FILE", "query QUERY-FILE", "Execute query in file QUERY-FILE"));
    puts(HELP_TEXT("r FILE", "result FILE     ", "Compare to result in file RESULTS-FILE"));


    puts("\nAdditional options:");
    puts(HELP_TEXT("d", "debug                ", "Increase debug message level"));
    puts(HELP_TEXT("F", "data-format NAME     ", "Set the data source format NAME (default: " DEFAULT_DATA_FORMAT_NAME_GRAPH ")"));
    puts(HELP_TEXT("h", "help                 ", "Print this help, then exit"));
    puts(HELP_TEXT("Q URI", "query-base-uri URI", "Set the base URI for the query"));
    puts(HELP_TEXT("R", "result-format NAME   ", "Set the result format NAME (default: " DEFAULT_RESULT_FORMAT_NAME ")"));
    puts("    For variable bindings and boolean results:");

    for(i = 0; 1; i++) {
      const raptor_syntax_description* desc;
 
      desc = rasqal_world_get_query_results_format_description(world, i);
      if(!desc)
         break;
 
      if(desc->flags & RASQAL_QUERY_RESULTS_FORMAT_FLAG_READER) {
        printf("      %-10s     %s", desc->names[0], desc->label);
        if(!strcmp(desc->names[0], DEFAULT_RESULT_FORMAT_NAME))
          puts(" (default)");
        else
          putchar('\n');
      }
    }

    puts("    For RDF graph results:");

    for(i = 0; 1; i++) {
      const raptor_syntax_description *desc;
      desc = raptor_world_get_parser_description(raptor_world_ptr, i);
      if(!desc)
        break;

      printf("      %-15s%s", desc->names[0], desc->label);
      if(!strcmp(desc->names[0], DEFAULT_DATA_FORMAT_NAME_GRAPH))
        puts(" (default)");
      else
        putchar('\n');
    }
    puts(HELP_TEXT("v", "version              ", "Print the Rasqal version"));

    puts("\nReport bugs to http://bugs.librdf.org/");

    rasqal_free_world(world);
    
    exit(0);
  }


  /* Compute query base URI from filename or passed in -Q QUERY-BASE-URI */
  if(!query_base_uri_string) {
    query_base_uri_string = raptor_uri_filename_to_uri_string(query_filename);
    free_query_base_uri_string = 1;
  }
  
  query_base_uri = raptor_new_uri(raptor_world_ptr, query_base_uri_string);
  if(!query_base_uri) {
    fprintf(stderr, "%s: Failed to create URI for %s\n",
            program, query_base_uri_string);
    return(1);
  }

  /* Read query from file into a string */
  query_string = rasqal_cmdline_read_file_string(world, query_filename,
                                                 "query file", &query_len);
  if(!query_string) {
    rc = 1;
    goto tidy_setup;
  }


  /* Report information */
  if(verbose) {
    fprintf(stderr, "%s: Reading query in language %s from file %s  URI %s:\n", 
            program, query_language, query_filename,
            raptor_uri_as_string(query_base_uri));
    if(verbose > 1)
      fprintf(stderr, "%s\n", (const char*)query_string);
    fprintf(stderr, "%s: Reading results from file '%s'\n", 
            program, result_filename);
  }


  /* Parse and prepare query */
  rq = check_query_init_query(world, query_language, query_string,
                              query_base_uri, data_graphs);
  rasqal_free_memory(query_string);
  if(!rq) {
    fprintf(stderr, "%s: Parsing query in %s failed\n", program,
            query_filename);
    goto tidy_query;
  }

  /* Query prepared OK - we now know the query details such as result type */


  /* Read expected results */
  if(1) {
    results_type = rasqal_query_get_result_type(rq);
    fprintf(stderr, "%s: Expecting result type %d\n", program, results_type);

    /* Read result file */
    result_iostr = raptor_new_iostream_from_filename(raptor_world_ptr,
                                                     result_filename);
    if(!result_iostr) {
      fprintf(stderr, "%s: result file '%s' open failed - %s\n", 
              program, result_filename, strerror(errno));
      rc = 1;
      goto tidy_setup;
    }


    switch(results_type) {
      case RASQAL_QUERY_RESULTS_BINDINGS:
      case RASQAL_QUERY_RESULTS_BOOLEAN:
        /* read results via rasqal query results format */
        expected_results = rasqal_cmdline_read_results(world,
                                                       raptor_world_ptr,
                                                       results_type,
                                                       result_iostr,
                                                       result_filename,
                                                       result_format_name);
        raptor_free_iostream(result_iostr); result_iostr = NULL;
        if(!expected_results) {
          fprintf(stderr, "%s: Failed to create query results\n", program);
          rc = 1;
          goto tidy_setup;
        }

        break;

      case RASQAL_QUERY_RESULTS_GRAPH:
        /* read results via raptor parser */

        if(1) {
          const char* format_name = NULL;

          if(result_format_name) {
            if(!raptor_world_is_parser_name(raptor_world_ptr,
                                            result_format_name)) {
              fprintf(stderr,
                      "%s: invalid parser name `%s' for `" HELP_ARG(R, result-format) "'\n\n",
                      program, result_format_name);
            } else
              format_name = result_format_name;
          }

          if(!format_name)
            format_name = DEFAULT_RESULT_FORMAT_NAME;

          ds = rasqal_new_dataset(world);
          if(!ds) {
            fprintf(stderr, "%s: Failed to create dataset", program);
            rc = 1;
            goto tidy_setup;
          }

          if(rasqal_dataset_load_graph_iostream(ds, format_name, 
                                                result_iostr, NULL)) {
            fprintf(stderr, "%s: Failed to load graph into dataset", program);
            rc = 1;
            goto tidy_setup;
          }

          raptor_free_iostream(result_iostr); result_iostr = NULL;

          /* FIXME
           *
           * The code at this point should do something with triples
           * in the dataset; save them for later to compare them to
           * the expected triples.  that requires a triples compare
           * OR a true RDF graph compare.
           *
           * Deleting the dataset here frees the triples just loaded.
           */
          rasqal_free_dataset(ds); ds = NULL;
        }
        break;
        
      case RASQAL_QUERY_RESULTS_SYNTAX:
      case RASQAL_QUERY_RESULTS_UNKNOWN:
        /* failure */
        fprintf(stderr,
                "%s: Reading %s query results format is not supported",
                program, rasqal_query_results_type_label(results_type));
        rc = 1;
        goto tidy_setup;
    }
    
  }


  /* save results for query execution so we can print and rewind */
  rasqal_query_set_store_results(rq, 1);

  results = rasqal_query_execute(rq);
  if(results) {

    switch(results_type) {
      case RASQAL_QUERY_RESULTS_BINDINGS:
        fprintf(stderr, "%s: Expected bindings results:\n", program);
        rasqal_cmdline_print_bindings_results_simple(program, expected_results,
                                                     stderr, 1, 0);
        
        fprintf(stderr, "%s: Actual bindings results:\n", program);
        rasqal_cmdline_print_bindings_results_simple(program, results,
                                                     stderr, 1, 0);

        rasqal_query_results_rewind(expected_results);
        rasqal_query_results_rewind(results);

        /* FIXME: should NOT do this if results are expected to be ordered */
        rasqal_query_results_sort(expected_results);
        rasqal_query_results_sort(results);

        if(1) {
          rasqal_results_compare* rrc;
          rrc = rasqal_new_results_compare(world,
                                          expected_results, "expected",
                                          results, "actual");
          rasqal_results_compare_set_log_handler(rrc, world,
                                                 check_query_log_handler);
          rc = !rasqal_results_compare_compare(rrc);
          rasqal_free_results_compare(rrc); rrc = NULL;
        }
        
        break;
        
      case RASQAL_QUERY_RESULTS_BOOLEAN:
        if(1) {
          int expected_boolean = rasqal_query_results_get_boolean(expected_results);
          int actual_boolean = rasqal_query_results_get_boolean(results);
          RASQAL_DEBUG2("Expected boolean result: %d\n", expected_boolean);
          RASQAL_DEBUG2("Actual boolean result: %d\n", actual_boolean);

          rc = (expected_boolean != actual_boolean);
        }
        break;

      case RASQAL_QUERY_RESULTS_GRAPH:
      case RASQAL_QUERY_RESULTS_SYNTAX:
      case RASQAL_QUERY_RESULTS_UNKNOWN:
        /* failure */
        fprintf(stderr, "%s: Query result format %d cannot be tested.", 
                program, results_type);
        rc = 1;
        goto tidy_setup;
    }
  } else
    rc = 1;


  if(verbose) {
    fprintf(stdout, "%s: Result: %s\n", program, rc ? "FAILURE" : "success");
  }

  if(results) {
    rasqal_free_query_results(results); results = NULL;
  }


  tidy_query:
  if(rq)
    rasqal_free_query(rq);


  tidy_setup:
  if(expected_results)
    rasqal_free_query_results(expected_results);

  if(results)
    rasqal_free_query_results(results);

  if(result_iostr)
    raptor_free_iostream(result_iostr);
  
  if(ds)
    rasqal_free_dataset(ds);

  if(free_query_base_uri_string)
    raptor_free_memory(query_base_uri_string);

  if(query_base_uri)
    raptor_free_uri(query_base_uri);

  if(data_graphs)
    raptor_free_sequence(data_graphs);

  rasqal_free_world(world);
  
  return (rc);
}
Exemplo n.º 5
0
/*
 * rasqal_query_results_write_sparql_xml:
 * @iostr: #raptor_iostream to write the query results to
 * @results: #rasqal_query_results query results input
 * @base_uri: #raptor_uri base URI of the output format
 *
 * Write the fourth version of the SPARQL 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_sparql_xml(rasqal_query_results_formatter* formatter,
                                      raptor_iostream *iostr,
                                      rasqal_query_results* results,
                                      raptor_uri *base_uri)
{
  int rc=1;
  rasqal_world* world = rasqal_query_results_get_world(results);
  raptor_xml_writer* xml_writer=NULL;
  raptor_namespace *res_ns=NULL;
  raptor_namespace_stack *nstack=NULL;
  raptor_xml_element *sparql_element=NULL;
  raptor_xml_element *results_element=NULL;
  raptor_xml_element *result_element=NULL;
  raptor_xml_element *element1=NULL;
  raptor_xml_element *binding_element=NULL;
  raptor_xml_element *variable_element=NULL;
  raptor_qname **attrs=NULL;
  int i;

  if(!rasqal_query_results_is_bindings(results) &&
     !rasqal_query_results_is_boolean(results)) {
    rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR,
                            NULL,
                            "Can only write XML format v3 for variable binding and boolean results");
    return 1;
  }
  

  nstack = raptor_new_namespaces(world->raptor_world_ptr, 1);
  if(!nstack)
    return 1;

  xml_writer = raptor_new_xml_writer(world->raptor_world_ptr,
                                     nstack,
                                     iostr);
  if(!xml_writer)
    goto tidy;

  res_ns=raptor_new_namespace(nstack,
                              NULL,
                              (const unsigned char*)"http://www.w3.org/2005/sparql-results#",
                              0);
  if(!res_ns)
    goto tidy;

  sparql_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  (const unsigned char*)"sparql",
                                                                  NULL, base_uri);
  if(!sparql_element)
    goto tidy;

  raptor_xml_writer_start_element(xml_writer, sparql_element);
  raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1);

  /*   <head> */
  element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                            (const unsigned char*)"head",
                                                            NULL, base_uri);
  if(!element1)
    goto tidy;

  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;
      name=rasqal_query_results_get_binding_name(results, i);
      if(!name)
        break;
      
      /*     <variable name="x"/> */
      variable_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                        (const unsigned char*)"variable",
                                                                        NULL, base_uri);
      if(!variable_element)
        goto tidy;
      
      attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
      if(!attrs)
        goto tidy;
      attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                            res_ns,
                                                            (const unsigned char*)"name",
                                                            (const unsigned char*)name); /* attribute value */
      if(!attrs[0]) {
        raptor_free_memory((void*)attrs);
        goto tidy;
      }

      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);
      variable_element=NULL;
    }
  }

  /* FIXME - could add <link> inside <head> */

    
  /*   </head> */
  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);
  element1=NULL;


  /* Boolean Results */
  if(rasqal_query_results_is_boolean(results)) {
    result_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    (const unsigned char*)"boolean",
                                                                    NULL, base_uri);
    if(!result_element)
      goto tidy;

    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> */
  results_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                   (const unsigned char*)"results",
                                                                   NULL, base_uri);
  if(!results_element)
    goto tidy;

  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_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  (const unsigned char*)"result",
                                                                  NULL, base_uri);
  if(!result_element)
    goto tidy;

  while(!rasqal_query_results_finished(results)) {
    /*     <result> */
    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<rasqal_query_results_get_bindings_count(results); i++) {
      const unsigned char *name=rasqal_query_results_get_binding_name(results, i);
      rasqal_literal *l=rasqal_query_results_get_binding_value(results, i);

      /*       <binding> */
      binding_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                       (const unsigned char*)"binding",
                                                                       NULL, base_uri);
      if(!binding_element)
        goto tidy;

      attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
      if(!attrs)
        goto tidy;
      attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                            res_ns,
                                                            (const unsigned char*)"name",
                                                            name);

      if(!attrs[0]) {
        raptor_free_memory((void*)attrs);
        goto tidy;
      }

      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) {
        element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  (const unsigned char*)"unbound",
                                                                  NULL, base_uri);
        if(!element1)
          goto tidy;
        raptor_xml_writer_empty_element(xml_writer, element1);

      } else switch(l->type) {
        case RASQAL_LITERAL_URI:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    (const unsigned char*)"uri",
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;
          
          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:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    (const unsigned char*)"bnode",
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;
          
          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:
        case RASQAL_LITERAL_UDT:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    (const unsigned char*)"literal",
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;

          if(l->language || l->datatype) {
            attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
            if(!attrs)
              goto tidy;

            if(l->language)
              attrs[0]=raptor_new_qname(nstack,
                                        (const unsigned char*)"xml:lang",
                                        (const unsigned char*)l->language);
            else
              attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                                    res_ns,
                                                                    (const unsigned char*)"datatype",
                                                                    (const unsigned char*)raptor_uri_as_string(l->datatype));
            if(!attrs[0]) {
              raptor_free_memory((void*)attrs);
              goto tidy;
            }

            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_XSD_STRING:
        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_INTEGER_SUBTYPE:

        case RASQAL_LITERAL_UNKNOWN:
        default:
          rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR,
                                  NULL,
                                  "Cannot turn literal type %d into XML", 
                                  l->type);
          goto tidy;
        }

      if(element1) {
        raptor_free_xml_element(element1);
        element1=NULL;
      }

      /*       </binding> */
      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);
      binding_element=NULL;
    }

    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_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);

  results3done:

  rc=0;

  raptor_xml_writer_end_element(xml_writer, sparql_element);
  raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1);

  tidy:
  if(element1)
    raptor_free_xml_element(element1);
  if(variable_element)
    raptor_free_xml_element(variable_element);
  if(binding_element)
    raptor_free_xml_element(binding_element);
  if(result_element)
    raptor_free_xml_element(result_element);
  if(results_element)
    raptor_free_xml_element(results_element);
  if(sparql_element)
    raptor_free_xml_element(sparql_element);
  if(res_ns)
    raptor_free_namespace(res_ns);
  if(xml_writer)
    raptor_free_xml_writer(xml_writer);
  if(nstack)
    raptor_free_namespaces(nstack);

  return rc;
}
/*
 * rasqal_query_results_write_sparql_xml:
 * @iostr: #raptor_iostream to write the query results to
 * @results: #rasqal_query_results query results input
 * @base_uri: #raptor_uri base URI of the output format
 *
 * Write the fourth version of the SPARQL 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_sparql_xml(rasqal_query_results_formatter* formatter,
                                      raptor_iostream *iostr,
                                      rasqal_query_results* results,
                                      raptor_uri *base_uri)
{
  int rc=1;
  rasqal_world* world = rasqal_query_results_get_world(results);
  raptor_xml_writer* xml_writer=NULL;
  raptor_namespace *res_ns=NULL;
  raptor_namespace_stack *nstack=NULL;
  raptor_xml_element *sparql_element=NULL;
  raptor_xml_element *results_element=NULL;
  raptor_xml_element *result_element=NULL;
  raptor_xml_element *element1=NULL;
  raptor_xml_element *binding_element=NULL;
  raptor_xml_element *variable_element=NULL;
  raptor_qname **attrs=NULL;
  int i;
  rasqal_query_results_type type;

  type = rasqal_query_results_get_type(results);

  if(type != RASQAL_QUERY_RESULTS_BINDINGS &&
     type != RASQAL_QUERY_RESULTS_BOOLEAN) {
    rasqal_log_error_simple(world, RAPTOR_LOG_LEVEL_ERROR,
                            NULL,
                            "Cannot write XML format v3 for %s query result format",
                            rasqal_query_results_type_label(type));
    return 1;
  }

  nstack = raptor_new_namespaces(world->raptor_world_ptr, 1);
  if(!nstack)
    return 1;

  xml_writer = raptor_new_xml_writer(world->raptor_world_ptr,
                                     nstack,
                                     iostr);
  if(!xml_writer)
    goto tidy;

  res_ns=raptor_new_namespace(nstack,
                              NULL,
                              RASQAL_GOOD_CAST(const unsigned char*, "http://www.w3.org/2005/sparql-results#"),
                              0);
  if(!res_ns)
    goto tidy;

  sparql_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  RASQAL_GOOD_CAST(const unsigned char*, "sparql"),
                                                                  NULL, base_uri);
  if(!sparql_element)
    goto tidy;

  raptor_xml_writer_start_element(xml_writer, sparql_element);
  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);

  /*   <head> */
  element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                            RASQAL_GOOD_CAST(const unsigned char*, "head"),
                                                            NULL, base_uri);
  if(!element1)
    goto tidy;

  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "  "), 2);
  raptor_xml_writer_start_element(xml_writer, element1);
  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);
  
  if(rasqal_query_results_is_bindings(results)) {
    for(i=0; 1; i++) {
      const unsigned char *name;
      name=rasqal_query_results_get_binding_name(results, i);
      if(!name)
        break;
      
      /*     <variable name="x"/> */
      variable_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                        RASQAL_GOOD_CAST(const unsigned char*,"variable"),
                                                                        NULL, base_uri);
      if(!variable_element)
        goto tidy;
      
      attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
      if(!attrs)
        goto tidy;
      attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                            res_ns,
                                                            RASQAL_GOOD_CAST(const unsigned char*,"name"),
                                                            RASQAL_GOOD_CAST(const unsigned char*, name)); /* attribute value */
      if(!attrs[0]) {
        raptor_free_memory((void*)attrs);
        goto tidy;
      }

      raptor_xml_element_set_attributes(variable_element, attrs, 1);
      
      raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "    "), 4);
      raptor_xml_writer_empty_element(xml_writer, variable_element);
      raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);
      
      raptor_free_xml_element(variable_element);
      variable_element=NULL;
    }
  }

  /* FIXME - could add <link> inside <head> */

    
  /*   </head> */
  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "  "), 2);
  raptor_xml_writer_end_element(xml_writer, element1);
  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);
  
  raptor_free_xml_element(element1);
  element1=NULL;


  /* Boolean Results */
  if(rasqal_query_results_is_boolean(results)) {
    result_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    RASQAL_GOOD_CAST(const unsigned char*, "boolean"),
                                                                    NULL, base_uri);
    if(!result_element)
      goto tidy;

    raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(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, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);

    goto results3done;
  }


  /* Variable Binding Results */

  /*   <results> */
  results_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                   RASQAL_GOOD_CAST(const unsigned char*, "results"),
                                                                   NULL, base_uri);
  if(!results_element)
    goto tidy;

  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "  "), 2);
  raptor_xml_writer_start_element(xml_writer, results_element);
  raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);


  /* declare result element for later multiple use */
  result_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  RASQAL_GOOD_CAST(const unsigned char*, "result"),
                                                                  NULL, base_uri);
  if(!result_element)
    goto tidy;

  while(!rasqal_query_results_finished(results)) {
    /*     <result> */
    raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "    "), 4);
    raptor_xml_writer_start_element(xml_writer, result_element);
    raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "\n"), 1);

    for(i=0; i<rasqal_query_results_get_bindings_count(results); i++) {
      const unsigned char *name=rasqal_query_results_get_binding_name(results, i);
      rasqal_literal *l=rasqal_query_results_get_binding_value(results, i);

      /*       <binding> */
      binding_element=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                       RASQAL_GOOD_CAST(const unsigned char*, "binding"),
                                                                       NULL, base_uri);
      if(!binding_element)
        goto tidy;

      attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
      if(!attrs)
        goto tidy;
      attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                            res_ns,
                                                            RASQAL_GOOD_CAST(const unsigned char*, "name"),
                                                            name);

      if(!attrs[0]) {
        raptor_free_memory((void*)attrs);
        goto tidy;
      }

      raptor_xml_element_set_attributes(binding_element, attrs, 1);
      

      raptor_xml_writer_raw_counted(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, "      "), 6);
      raptor_xml_writer_start_element(xml_writer, binding_element);

      if(!l) {
        element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                  RASQAL_GOOD_CAST(const unsigned char*, "unbound"),
                                                                  NULL, base_uri);
        if(!element1)
          goto tidy;
        raptor_xml_writer_empty_element(xml_writer, element1);

      } else switch(l->type) {
        case RASQAL_LITERAL_URI:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    RASQAL_GOOD_CAST(const unsigned char*, "uri"),
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;
          
          raptor_xml_writer_start_element(xml_writer, element1);
          raptor_xml_writer_cdata(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_string(l->value.uri)));
          raptor_xml_writer_end_element(xml_writer, element1);

          break;

        case RASQAL_LITERAL_BLANK:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    RASQAL_GOOD_CAST(const unsigned char*, "bnode"),
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;
          
          raptor_xml_writer_start_element(xml_writer, element1);
          raptor_xml_writer_cdata(xml_writer, RASQAL_GOOD_CAST(const unsigned char*, l->string));
          raptor_xml_writer_end_element(xml_writer, element1);
          break;

        case RASQAL_LITERAL_STRING:
        case RASQAL_LITERAL_UDT:
          element1=raptor_new_xml_element_from_namespace_local_name(res_ns,
                                                                    RASQAL_GOOD_CAST(const unsigned char*, "literal"),
                                                                    NULL, base_uri);
          if(!element1)
            goto tidy;

          if(l->language || l->datatype) {
            attrs=(raptor_qname **)raptor_alloc_memory(sizeof(raptor_qname*));
            if(!attrs)
              goto tidy;

            if(l->language)
              attrs[0]=raptor_new_qname(nstack,
                                        RASQAL_GOOD_CAST(const unsigned char*, "xml:lang"),
                                        RASQAL_GOOD_CAST(const unsigned char*, l->language));
            else
              attrs[0] = raptor_new_qname_from_namespace_local_name(world->raptor_world_ptr,
                                                                    res_ns,
                                                                    RASQAL_GOOD_CAST(const unsigned char*, "datatype"),
                                                                    RASQAL_GOOD_CAST(const unsigned char*, raptor_uri_as_string(l->datatype)));
            if(!attrs[0]) {
              raptor_free_memory((void*)attrs);
              goto tidy;
            }

            raptor_xml_element_set_attributes(element1, attrs, 1);
          }