diff options
author | Dave Beckett <dave@dajobe.org> | 2005-01-01 21:32:39 +0000 |
---|---|---|
committer | Dave Beckett <dave@dajobe.org> | 2005-01-01 21:32:39 +0000 |
commit | 870cdafbb11f5b5d94daad7a8c6dcdc743048f96 (patch) | |
tree | f53016c4246e6933612d53a35bac606cdfb44861 /src/raptor_serialize.c | |
parent | 80eca4deea1aa3e1da6d8e5f8bf43b5af70f6210 (diff) | |
download | raptor-870cdafbb11f5b5d94daad7a8c6dcdc743048f96.tar.gz |
Add XML Writer to raptor_rdfxml_serializer_context, delete depth.
(raptor_rdfxml_serialize_init): Delete depth stuff.
(raptor_rdfxml_serialize_terminate): Tidy up xml writer, namespaces
and rdf:RDF element.
(raptor_rdfxml_serialize_declare_namespace): Don't copy uri, prefixes
since raptor_new_namesapce_from_uri copies them anyway.
(raptor_rdfxml_serialize_start): Convert to use xml writer.
(raptor_rdfxml_serialize_write_xml_attribute): Deleted.
(raptor_rdfxml_serialize_statement, raptor_rdfxml_serialize_end):
Convert to use xml writer.
Diffstat (limited to 'src/raptor_serialize.c')
-rw-r--r-- | src/raptor_serialize.c | 466 |
1 files changed, 199 insertions, 267 deletions
diff --git a/src/raptor_serialize.c b/src/raptor_serialize.c index f7b9b613..985f8cea 100644 --- a/src/raptor_serialize.c +++ b/src/raptor_serialize.c @@ -883,9 +883,19 @@ raptor_serializer_get_locator(raptor_serializer *rdf_serializer) * Raptor RDF/XML serializer object */ typedef struct { - int depth; + /* Namespace stack */ raptor_namespace_stack *nstack; - raptor_namespace *rdf_ns; + + /* the rdf: namespace - this is destroyed when nstack above is deleted */ + raptor_namespace *rdf_nspace; + + /* the rdf:RDF element */ + raptor_xml_element* rdf_RDF_element; + + /* where the xml is being written */ + raptor_xml_writer *xml_writer; + + /* User declared namespaces */ raptor_sequence *namespaces; } raptor_rdfxml_serializer_context; @@ -905,13 +915,12 @@ raptor_rdfxml_serialize_init(raptor_serializer* serializer, const char *name) raptor_serializer_simple_error, serializer, 1); - context->depth=0; - context->rdf_ns=raptor_new_namespace(context->nstack, - (const unsigned char*)"rdf", - (const unsigned char*)raptor_rdf_namespace_uri, - context->depth); + context->rdf_nspace=raptor_new_namespace(context->nstack, + (const unsigned char*)"rdf", + (const unsigned char*)raptor_rdf_namespace_uri, + 0); - context->namespaces=raptor_new_sequence((raptor_sequence_free_handler*)raptor_free_namespace, NULL); + context->namespaces=raptor_new_sequence(NULL, NULL); return 0; } @@ -923,11 +932,28 @@ raptor_rdfxml_serialize_terminate(raptor_serializer* serializer) { raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; - /* Frees all namespaces on the stack, including context->rdf_ns */ + if(context->xml_writer) + raptor_free_xml_writer(context->xml_writer); + + if(context->rdf_RDF_element) + raptor_free_xml_element(context->rdf_RDF_element); + + if(context->rdf_nspace) + raptor_free_namespace(context->rdf_nspace); + + if(context->namespaces) { + int i; + + for(i=0; i< raptor_sequence_size(context->namespaces); i++) { + raptor_namespace* ns=(raptor_namespace*)raptor_sequence_get_at(context->namespaces, i); + if(ns) + raptor_free_namespace(ns); + } + raptor_free_sequence(context->namespaces); + } + if(context->nstack) raptor_free_namespaces(context->nstack); - if(context->namespaces) - raptor_free_sequence(context->namespaces); } @@ -938,18 +964,9 @@ raptor_rdfxml_serialize_declare_namespace(raptor_serializer* serializer, const unsigned char *prefix) { raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; - unsigned char *prefix_copy=NULL; raptor_namespace *ns; - - if(uri) - uri=raptor_uri_copy(uri); - if(prefix) { - size_t prefix_len=strlen((const char*)prefix); - prefix_copy=(unsigned char*)RAPTOR_MALLOC(cstring, prefix_len+1); - strncpy((char*)prefix_copy, (const char*)prefix, prefix_len+1); - } - ns=raptor_new_namespace_from_uri(context->nstack, prefix_copy, uri, 0); + ns=raptor_new_namespace_from_uri(context->nstack, prefix, uri, 0); if(!ns) return 1; @@ -963,86 +980,39 @@ static int raptor_rdfxml_serialize_start(raptor_serializer* serializer) { raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; - raptor_iostream *iostr=serializer->iostream; + raptor_xml_writer* xml_writer; + raptor_uri *base_uri=serializer->base_uri; int i; + raptor_uri_handler *uri_handler; + void *uri_context; + raptor_xml_element *element; + raptor_qname *qname; + + raptor_uri_get_handler(&uri_handler, &uri_context); + + xml_writer=raptor_new_xml_writer(context->nstack, + uri_handler, uri_context, + serializer->iostream, + raptor_serializer_simple_error, + serializer, + 1); + context->xml_writer=xml_writer; - raptor_iostream_write_string(iostr, - "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); - context->depth++; - raptor_namespaces_start_namespace(context->nstack, context->rdf_ns); + qname=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, + (const unsigned char*)"RDF", NULL); + element=raptor_new_xml_element(qname, NULL, raptor_uri_copy(base_uri)); + context->rdf_RDF_element=element; for(i=0; i< raptor_sequence_size(context->namespaces); i++) { raptor_namespace* ns=(raptor_namespace*)raptor_sequence_get_at(context->namespaces, i); - raptor_namespaces_start_namespace(context->nstack, ns); + raptor_xml_element_declare_namespace(context->rdf_RDF_element, ns); } - raptor_iostream_write_counted_string(iostr, "<rdf:RDF ", 9); - raptor_iostream_write_namespace(iostr, context->rdf_ns); - while(raptor_sequence_size(context->namespaces)) { - raptor_namespace* ns=(raptor_namespace*)raptor_sequence_pop(context->namespaces); - raptor_iostream_write_byte(iostr, ' '); - raptor_iostream_write_namespace(iostr, ns); - } - raptor_iostream_write_counted_string(iostr, ">\n", 2); - return 0; -} - - -/** - * raptor_rdfxml_serialize_write_xml_attribute - Write the attribute/value as an XML attribute, XML escaped to an iostream - * @world: &librdf_world world - * @attr: attribute name - * @value: attribute value - * @iostr: &raptor_iostream to print to - * - * Return value: non-0 on failure - **/ -static int -raptor_rdfxml_serialize_write_xml_attribute(raptor_serializer *serializer, - unsigned char *attr, - unsigned char *value, - raptor_iostream *iostr) -{ - size_t attr_len; - size_t len; - int escaped_len=0; - unsigned char *buffer; - unsigned char *p; - - attr_len=strlen((const char*)attr); - len=strlen((const char*)value); - - if(len) { - escaped_len=raptor_xml_escape_string(value, len, - NULL, 0, '"', - NULL, NULL); - if(escaped_len < 0) { - raptor_serializer_error(serializer, "Bad UTF-8 encoding found while XML escaping attribute '%s' value '%s'", attr, value); - return 1; - } - } - - buffer=(unsigned char*)RAPTOR_MALLOC(cstring, 1 + attr_len + 2 + escaped_len + 1 +1); - if(!buffer) - return 1; + raptor_xml_writer_raw(xml_writer, + (const unsigned char*)"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); - p=buffer; - *p++=' '; - strncpy((char*)p, (const char*)attr, attr_len); - p+= attr_len; - *p++='='; - *p++='"'; - if(escaped_len) { - raptor_xml_escape_string(value, len, - p, escaped_len, '"', - NULL, NULL); - p+= escaped_len; - } - *p++='"'; - *p='\0'; - - raptor_iostream_write_counted_string(iostr, buffer, p-buffer); - RAPTOR_FREE(cstring, buffer); + raptor_xml_writer_start_element(xml_writer, context->rdf_RDF_element); + raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); return 0; } @@ -1053,61 +1023,84 @@ static int raptor_rdfxml_serialize_statement(raptor_serializer* serializer, const raptor_statement *statement) { - /* raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; */ - raptor_iostream* iostr=serializer->iostream; + raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; + raptor_xml_writer* xml_writer=context->xml_writer; unsigned char* uri_string=NULL; /* predicate URI */ + unsigned char ordinal_name[20]; unsigned char* name=NULL; /* where to split predicate name */ - unsigned char* output_uri_string; - int name_is_rdf_ns=0; + unsigned char* subject_uri_string=NULL; + unsigned char* object_uri_string=NULL; char* nsprefix="ns0"; int rc; size_t len; + raptor_qname* rdf_Description_qname; + raptor_xml_element* rdf_Description_element; + raptor_uri* predicate_ns_uri=NULL; + raptor_namespace* predicate_ns=NULL; + int free_predicate_ns=0; + raptor_qname* predicate_qname=NULL; + raptor_xml_element* predicate_element=NULL; + raptor_qname **attrs; + int attrs_count=0; - if(statement->predicate_type != RAPTOR_IDENTIFIER_TYPE_ORDINAL) { + if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { + predicate_ns=context->rdf_nspace; + sprintf(ordinal_name, "_%d", *((int*)statement->predicate)); + name=ordinal_name; + } else { unsigned char *p; size_t uri_len; - + size_t name_len=1; + unsigned char c; + uri_string=raptor_uri_as_counted_string((raptor_uri*)statement->predicate, &uri_len); - if(!strncmp((const char*)uri_string, - raptor_rdf_namespace_uri, raptor_rdf_namespace_uri_len)) { - name=uri_string + raptor_rdf_namespace_uri_len; - name_is_rdf_ns=1; - nsprefix="rdf"; - } else { - size_t name_len=1; - - p= uri_string + uri_len-name_len; - while(p >= uri_string) { - if(raptor_xml_name_check(p, name_len, 10)) - name=p; - else if(name && p>uri_string && - !raptor_xml_name_check(p-1, name_len+1, 10)) - /* if next char would make name invalid, stop */ - break; - p--; name_len++; - } + p= uri_string + uri_len-name_len; + while(p >= uri_string) { + if(raptor_xml_name_check(p, name_len, 10)) + name=p; + else if(name && p>uri_string && + !raptor_xml_name_check(p-1, name_len+1, 10)) + /* if next char would make name invalid, stop */ + break; + p--; name_len++; + } - if(!name) { - raptor_serializer_error(serializer, "Cannot split predicate URI %s into an XML qname - skipping statement", uri_string); - return 1; - } + if(!name) { + raptor_serializer_error(serializer, "Cannot split predicate URI %s into an XML qname - skipping statement", uri_string); + return 1; } - } + c=*name; *name='\0'; + predicate_ns_uri=raptor_new_uri(uri_string); + *name=c; + + predicate_ns=raptor_namespaces_find_namespace_by_uri(context->nstack, + predicate_ns_uri); + if(!predicate_ns) { + predicate_ns=raptor_new_namespace_from_uri(context->nstack, + nsprefix, + predicate_ns_uri, 0); + free_predicate_ns=1; + } + raptor_free_uri(predicate_ns_uri); + } - raptor_iostream_write_string(iostr, " <rdf:Description"); + + rdf_Description_qname=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, + (unsigned const char*)"Description", NULL); + rdf_Description_element=raptor_new_xml_element(rdf_Description_qname, NULL, + raptor_uri_copy(serializer->base_uri)); + attrs=(raptor_qname **)RAPTOR_CALLOC(qnamearray, 3, sizeof(raptor_qname*)); + attrs_count=0; /* subject */ rc=0; switch(statement->subject_type) { case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: - rc=raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"rdf:nodeID", - (unsigned char*)statement->subject, - iostr); + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"nodeID", (unsigned char*)statement->subject); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: @@ -1116,16 +1109,14 @@ raptor_rdfxml_serialize_statement(raptor_serializer* serializer, case RAPTOR_IDENTIFIER_TYPE_RESOURCE: if(serializer->feature_relative_uris) - output_uri_string=raptor_uri_to_relative_uri_string(serializer->base_uri, + subject_uri_string=raptor_uri_to_relative_uri_string(serializer->base_uri, (raptor_uri*)statement->subject); else - output_uri_string=raptor_uri_as_string((raptor_uri*)statement->subject); - rc=raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"rdf:about", - output_uri_string, - iostr); - if(serializer->feature_relative_uris) - RAPTOR_FREE(cstring, output_uri_string); + subject_uri_string=raptor_uri_as_string((raptor_uri*)statement->subject); + + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"about", subject_uri_string); + RAPTOR_FREE(cstring, subject_uri_string); + break; case RAPTOR_IDENTIFIER_TYPE_PREDICATE: @@ -1135,164 +1126,94 @@ raptor_rdfxml_serialize_statement(raptor_serializer* serializer, raptor_serializer_error(serializer, "Do not know how to serialize node type %d\n", statement->subject_type); } - if(rc) { - raptor_iostream_write_counted_string(iostr, "/>\n", 3); - return 1; - } + if(attrs_count) + raptor_xml_element_set_attributes(rdf_Description_element, attrs, attrs_count); - raptor_iostream_write_counted_string(iostr, ">\n", 2); + raptor_xml_writer_cdata_counted(xml_writer, " ", 2); + raptor_xml_writer_start_element(xml_writer, rdf_Description_element); + raptor_xml_writer_cdata_counted(xml_writer, "\n", 1); /* predicate */ - if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { - raptor_iostream_write_counted_string(iostr, " <rdf:_", 10); - raptor_iostream_write_decimal(iostr, *((int*)statement->predicate)); - } else { - raptor_iostream_write_counted_string(iostr, " <", 5); - raptor_iostream_write_string(iostr, nsprefix); - raptor_iostream_write_byte(iostr, ':'); - raptor_iostream_write_string(iostr, (const char*)name); - - if(!name_is_rdf_ns) { - int escaped_len=0; - unsigned char *buffer; - unsigned char *p; - - len=name-uri_string; - - raptor_iostream_write_counted_string(iostr, " xmlns:", 7); - raptor_iostream_write_string(iostr, nsprefix); - raptor_iostream_write_byte(iostr, '='); - - if(len) { - escaped_len=raptor_xml_escape_string(uri_string, len, - NULL, 0, '"', - NULL, NULL); - if(escaped_len < 0) { - raptor_serializer_error(serializer, - "Bad UTF-8 encoding found while XML escaping namespace URI '%s'", uri_string); - return 1; - } - } - - /* " + string + " + \0 */ - buffer=(unsigned char*)RAPTOR_MALLOC(cstring, 1 + escaped_len + 1 + 1); - if(!buffer) - return 1; - - p=buffer; - *p++='"'; - if(escaped_len) { - raptor_xml_escape_string(uri_string, len, - p, escaped_len, '"', - NULL, NULL); - p+= escaped_len; - } - *p++='"'; - *p='\0'; + predicate_qname=raptor_new_qname_from_namespace_local_name(predicate_ns, + name, NULL); + predicate_element=raptor_new_xml_element(predicate_qname, NULL, + raptor_uri_copy(serializer->base_uri)); - raptor_iostream_write_counted_string(iostr, (const char*)buffer, p-buffer); - RAPTOR_FREE(cstring, buffer); - } - } /* object */ + attrs=(raptor_qname **)RAPTOR_CALLOC(qnamearray, 3, sizeof(raptor_qname*)); + attrs_count=0; + switch(statement->object_type) { case RAPTOR_IDENTIFIER_TYPE_LITERAL: case RAPTOR_IDENTIFIER_TYPE_XML_LITERAL: - if(statement->object_literal_language) { - if(raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"xml:lang", - (unsigned char*)statement->object_literal_language, - iostr)) - return 1; - } + if(statement->object_literal_language) + attrs[attrs_count++]=raptor_new_qname(context->nstack, + (unsigned char*)"xml:lang", + (unsigned char*)statement->object_literal_language, + raptor_serializer_simple_error, + serializer); len=strlen((const char*)statement->object); if(statement->object_type == RAPTOR_IDENTIFIER_TYPE_XML_LITERAL) { - raptor_iostream_write_string(iostr, " rdf:parseType=\"Literal\">"); + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"parseType", (const unsigned char*)"Literal"); + raptor_xml_element_set_attributes(predicate_element, attrs, attrs_count); + + raptor_xml_writer_cdata_counted(xml_writer, " ", 4); + raptor_xml_writer_start_element(xml_writer, predicate_element); + /* Print without escaping XML */ if(len) - raptor_iostream_write_counted_string(iostr, (const char*)statement->object, len); + raptor_xml_writer_raw_counted(xml_writer, + (const char*)statement->object, len); } else { - int xml_string_len; - - if(statement->object_literal_datatype) { - if(raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"rdf:datatype", - (unsigned char*)raptor_uri_as_string((raptor_uri*)statement->object_literal_datatype), - iostr)) - return 1; - } - - raptor_iostream_write_byte(iostr, '>'); + if(statement->object_literal_datatype) + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"datatype", (unsigned char*)raptor_uri_as_string((raptor_uri*)statement->object_literal_datatype)); - if(len) { - xml_string_len=raptor_xml_escape_string((const unsigned char*)statement->object, len, - NULL, 0, 0, - NULL, NULL); - if(xml_string_len < 0) { - raptor_serializer_error(serializer, - "Bad UTF-8 encoding found while XML escaping element content '%s'", statement->object); - return 1; - } - - if(xml_string_len == (int)len) - raptor_iostream_write_string(iostr, statement->object); - else { - unsigned char *xml_string; - - xml_string=(unsigned char*)RAPTOR_MALLOC(cstring, xml_string_len+1); - xml_string_len=raptor_xml_escape_string((const unsigned char*)statement->object, len, - xml_string, xml_string_len, 0, - NULL, NULL); - raptor_iostream_write_counted_string(iostr, xml_string, xml_string_len); - RAPTOR_FREE(cstring, xml_string); - } - } + raptor_xml_element_set_attributes(predicate_element, attrs, attrs_count); + raptor_xml_writer_cdata_counted(xml_writer, " ", 4); + raptor_xml_writer_start_element(xml_writer, predicate_element); + + if(len) + raptor_xml_writer_cdata_counted(xml_writer, + (const unsigned char*)statement->object, len); } - raptor_iostream_write_counted_string(iostr, "</", 2); - raptor_iostream_write_string(iostr, nsprefix); - raptor_iostream_write_byte(iostr, ':'); - if(statement->predicate_type == RAPTOR_IDENTIFIER_TYPE_ORDINAL) { - raptor_iostream_write_byte(iostr, '_'); - raptor_iostream_write_decimal(iostr, *((int*)statement->predicate)); - } else - raptor_iostream_write_string(iostr, (const char*)name); - raptor_iostream_write_byte(iostr, '>'); + raptor_xml_writer_end_element(xml_writer, predicate_element); + raptor_xml_writer_cdata_counted(xml_writer, "\n", 1); + break; case RAPTOR_IDENTIFIER_TYPE_ANONYMOUS: - if(raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"rdf:nodeID", - (unsigned char*)statement->object, - iostr)) - return 1; - raptor_iostream_write_string(iostr, "/>"); + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"nodeID", (unsigned char*)statement->object); + + raptor_xml_element_set_attributes(predicate_element, attrs, attrs_count); + + raptor_xml_writer_cdata_counted(xml_writer, " ", 4); + raptor_xml_writer_empty_element(xml_writer, predicate_element); + raptor_xml_writer_cdata_counted(xml_writer, "\n", 1); break; case RAPTOR_IDENTIFIER_TYPE_RESOURCE: /* must be URI */ if(serializer->feature_relative_uris) - output_uri_string=raptor_uri_to_relative_uri_string(serializer->base_uri, + object_uri_string=raptor_uri_to_relative_uri_string(serializer->base_uri, (raptor_uri*)statement->object); else - output_uri_string=raptor_uri_as_string((raptor_uri*)statement->object); - if(raptor_rdfxml_serialize_write_xml_attribute(serializer, - (unsigned char*)"rdf:resource", - output_uri_string, - iostr)) { - if(serializer->feature_relative_uris) - RAPTOR_FREE(cstring, output_uri_string); - return 1; - } - if(serializer->feature_relative_uris) - RAPTOR_FREE(cstring, output_uri_string); - raptor_iostream_write_string(iostr, "/>"); + object_uri_string=raptor_uri_as_string((raptor_uri*)statement->object); + + attrs[attrs_count++]=raptor_new_qname_from_namespace_local_name(context->rdf_nspace, (const unsigned char*)"resource", object_uri_string); + RAPTOR_FREE(cstring, object_uri_string); + + raptor_xml_element_set_attributes(predicate_element, attrs, 1); + + raptor_xml_writer_cdata_counted(xml_writer, " ", 4); + raptor_xml_writer_empty_element(xml_writer, predicate_element); + raptor_xml_writer_cdata_counted(xml_writer, "\n", 1); break; case RAPTOR_IDENTIFIER_TYPE_ORDINAL: @@ -1304,7 +1225,17 @@ raptor_rdfxml_serialize_statement(raptor_serializer* serializer, raptor_serializer_error(serializer, "Do not know how to serialize node type %d\n", statement->object_type); } - raptor_iostream_write_string(iostr, "\n </rdf:Description>\n"); + raptor_free_xml_element(predicate_element); + if(free_predicate_ns) { + raptor_free_namespace(predicate_ns); + } + + + raptor_xml_writer_cdata_counted(xml_writer, " ", 2); + raptor_xml_writer_end_element(xml_writer, rdf_Description_element); + raptor_xml_writer_cdata_counted(xml_writer, "\n", 1); + + raptor_free_xml_element(rdf_Description_element); return 0; } @@ -1315,13 +1246,14 @@ static int raptor_rdfxml_serialize_end(raptor_serializer* serializer) { raptor_rdfxml_serializer_context* context=(raptor_rdfxml_serializer_context*)serializer->context; - raptor_iostream *iostr=serializer->iostream; - - raptor_iostream_write_counted_string(iostr, "</rdf:RDF>\n", 11); + raptor_xml_writer* xml_writer=context->xml_writer; - raptor_namespaces_end_for_depth(context->nstack, context->depth); - context->depth--; + raptor_xml_writer_end_element(xml_writer, context->rdf_RDF_element); + raptor_xml_writer_raw_counted(xml_writer, (const unsigned char*)"\n", 1); + raptor_free_xml_element(context->rdf_RDF_element); + context->rdf_RDF_element=NULL; + return 0; } |