/** * raptor_new_xml_element_from_namespace_local_name: * @ns: namespace * @name: the XML element local name * @xml_language: the in-scope XML language (or NULL) * @xml_base: base uri (or NULL) * * Constructor - create a new XML element from an XML namespace and a local name * * Added in 1.4.16. * * Return value: a new #raptor_xml_element or NULL on failure */ raptor_xml_element* raptor_new_xml_element_from_namespace_local_name(raptor_namespace *ns, const unsigned char *name, const unsigned char *xml_language, raptor_uri *xml_base) { raptor_uri *base_uri_copy; raptor_qname *qname; raptor_xml_element *element = NULL; qname = raptor_new_qname_from_namespace_local_name(ns->nstack->world, ns, name, NULL); if(qname) { base_uri_copy = xml_base ? raptor_uri_copy(xml_base) : NULL; element = raptor_new_xml_element(qname, xml_language, base_uri_copy); if(!element) { raptor_free_qname(qname); if(base_uri_copy) raptor_free_uri(base_uri_copy); } } return element; }
/* start of an element */ void raptor_sax2_start_element(void* user_data, const unsigned char *name, const unsigned char **atts) { raptor_sax2* sax2=(raptor_sax2*)user_data; raptor_qname* el_name; unsigned char **xml_atts_copy=NULL; size_t xml_atts_size=0; int all_atts_count=0; int ns_attributes_count=0; raptor_qname** named_attrs=NULL; raptor_xml_element* xml_element=NULL; unsigned char *xml_language=NULL; raptor_uri *xml_base=NULL; if(sax2->failed) return; #ifdef RAPTOR_XML_EXPAT #ifdef EXPAT_UTF8_BOM_CRASH sax2->tokens_count++; #endif #endif #ifdef RAPTOR_XML_LIBXML if(atts) { int i; /* Do XML attribute value normalization */ for (i = 0; atts[i]; i+=2) { unsigned char *value=(unsigned char*)atts[i+1]; unsigned char *src = value; unsigned char *dst = xmlStrdup(value); if(!dst) { raptor_log_error_to_handlers(sax2->world, sax2->error_handlers, RAPTOR_LOG_LEVEL_FATAL, sax2->locator, "Out of memory"); return; } atts[i+1]=dst; while (*src == 0x20 || *src == 0x0d || *src == 0x0a || *src == 0x09) src++; while (*src) { if (*src == 0x20 || *src == 0x0d || *src == 0x0a || *src == 0x09) { while (*src == 0x20 || *src == 0x0d || *src == 0x0a || *src == 0x09) src++; if (*src) *dst++ = 0x20; } else { *dst++ = *src++; } } *dst = '\0'; xmlFree(value); } } #endif raptor_sax2_inc_depth(sax2); if(atts) { int i; /* Save passed in XML attributes pointers so we can * NULL the pointers when they get handled below (various atts[i]=NULL) */ for (i = 0; atts[i]; i++) ; xml_atts_size=sizeof(unsigned char*) * i; if(xml_atts_size) { xml_atts_copy=(unsigned char**)RAPTOR_MALLOC(cstringpointer,xml_atts_size); if(!xml_atts_copy) goto fail; memcpy(xml_atts_copy, atts, xml_atts_size); } /* XML attributes processing: * xmlns* - XML namespaces (Namespaces in XML REC) * Deleted and used to synthesise namespaces declarations * xml:lang - XML language (XML REC) * Deleted and optionally normalised to lowercase * xml:base - XML Base (XML Base REC) * Deleted and used to set the in-scope base URI for this XML element */ for (i = 0; atts[i]; i+= 2) { all_atts_count++; if(strncmp((char*)atts[i], "xml", 3)) { /* count and skip non xml* attributes */ ns_attributes_count++; continue; } /* synthesise the XML namespace events */ if(!memcmp((const char*)atts[i], "xmlns", 5)) { const unsigned char *prefix=atts[i][5] ? &atts[i][6] : NULL; const unsigned char *namespace_name=atts[i+1]; raptor_namespace* nspace; nspace=raptor_new_namespace(&sax2->namespaces, prefix, namespace_name, raptor_sax2_get_depth(sax2)); if(nspace) { raptor_namespaces_start_namespace(&sax2->namespaces, nspace); if(sax2->namespace_handler) (*sax2->namespace_handler)(sax2->user_data, nspace); } } else if(!strcmp((char*)atts[i], "xml:lang")) { xml_language=(unsigned char*)RAPTOR_MALLOC(cstring, strlen((char*)atts[i+1])+1); if(!xml_language) { raptor_log_error_to_handlers(sax2->world, sax2->error_handlers, RAPTOR_LOG_LEVEL_FATAL, sax2->locator, "Out of memory"); goto fail; } /* optionally normalize language to lowercase */ if(sax2->feature_normalize_language) { unsigned char *from=(unsigned char*)atts[i+1]; unsigned char *to=xml_language; while(*from) { if(isupper(*from)) *to++ =tolower(*from++); else *to++ =*from++; } *to='\0'; } else strcpy((char*)xml_language, (char*)atts[i+1]); } else if(!strcmp((char*)atts[i], "xml:base")) { raptor_uri* base_uri; raptor_uri* xuri; base_uri=raptor_sax2_inscope_base_uri(sax2); xuri=raptor_new_uri_relative_to_base_v2(sax2->world, base_uri, atts[i+1]); xml_base=raptor_new_uri_for_xmlbase_v2(sax2->world, xuri); raptor_free_uri_v2(sax2->world, xuri); } /* delete all xml attributes whether processed above or not */ atts[i]=NULL; } } /* Create new element structure */ el_name=raptor_new_qname(&sax2->namespaces, name, NULL, (raptor_simple_message_handler)raptor_sax2_simple_error, sax2); if(!el_name) goto fail; xml_element=raptor_new_xml_element(el_name, xml_language, xml_base); if(!xml_element) { raptor_free_qname(el_name); goto fail; } /* xml_language,xml_base now owned by xml_element */ xml_language = NULL; xml_base = NULL; /* Turn string attributes into namespaced-attributes */ if(ns_attributes_count) { int i; int offset = 0; /* Allocate new array to hold namespaced-attributes */ named_attrs=(raptor_qname**)RAPTOR_CALLOC(raptor_qname_array, ns_attributes_count, sizeof(raptor_qname*)); if(!named_attrs) { raptor_log_error_to_handlers(sax2->world, sax2->error_handlers, RAPTOR_LOG_LEVEL_FATAL, sax2->locator, "Out of memory"); goto fail; } for (i = 0; i < all_atts_count; i++) { raptor_qname* attr; /* Skip previously processed attributes */ if(!atts[i<<1]) continue; /* namespace-name[i] stored in named_attrs[i] */ attr=raptor_new_qname(&sax2->namespaces, atts[i<<1], atts[(i<<1)+1], (raptor_simple_message_handler)raptor_sax2_simple_error, sax2); if(!attr) { /* failed - tidy up and return */ int j; for (j=0; j < i; j++) RAPTOR_FREE(raptor_qname, named_attrs[j]); RAPTOR_FREE(raptor_qname_array, named_attrs); goto fail; } named_attrs[offset++]=attr; } } /* end if ns_attributes_count */ if(named_attrs) raptor_xml_element_set_attributes(xml_element, named_attrs, ns_attributes_count); raptor_xml_element_push(sax2, xml_element); if(sax2->start_element_handler) sax2->start_element_handler(sax2->user_data, xml_element); if(xml_atts_copy) { /* Restore passed in XML attributes, free the copy */ memcpy((void*)atts, xml_atts_copy, xml_atts_size); RAPTOR_FREE(cstringpointer, xml_atts_copy); } return; fail: if(xml_atts_copy) RAPTOR_FREE(cstringpointer, xml_atts_copy); if(xml_base) raptor_free_uri_v2(sax2->world, xml_base); if(xml_language) RAPTOR_FREE(cstring, xml_language); if(xml_element) raptor_free_xml_element(xml_element); }
int main(int argc, char *argv[]) { raptor_world *world; const char *program = raptor_basename(argv[0]); raptor_iostream *iostr; raptor_namespace_stack *nstack; raptor_namespace* foo_ns; raptor_xml_writer* xml_writer; raptor_uri* base_uri; raptor_qname* el_name; raptor_xml_element *element; unsigned long offset; raptor_qname **attrs; raptor_uri* base_uri_copy = NULL; /* for raptor_new_iostream_to_string */ void *string = NULL; size_t string_len = 0; world = raptor_new_world(); if(!world || raptor_world_open(world)) exit(1); iostr = raptor_new_iostream_to_string(world, &string, &string_len, NULL); if(!iostr) { fprintf(stderr, "%s: Failed to create iostream to string\n", program); exit(1); } nstack = raptor_new_namespaces(world, 1); xml_writer = raptor_new_xml_writer(world, nstack, iostr); if(!xml_writer) { fprintf(stderr, "%s: Failed to create xml_writer to iostream\n", program); exit(1); } base_uri = raptor_new_uri(world, base_uri_string); foo_ns = raptor_new_namespace(nstack, (const unsigned char*)"foo", (const unsigned char*)"http://example.org/foo-ns#", 0); el_name = raptor_new_qname_from_namespace_local_name(world, foo_ns, (const unsigned char*)"bar", NULL); base_uri_copy = base_uri ? raptor_uri_copy(base_uri) : NULL; element = raptor_new_xml_element(el_name, NULL, /* language */ base_uri_copy); raptor_xml_writer_start_element(xml_writer, element); raptor_xml_writer_cdata_counted(xml_writer, (const unsigned char*)"hello\n", 6); raptor_xml_writer_comment_counted(xml_writer, (const unsigned char*)"comment", 7); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n"); raptor_xml_writer_end_element(xml_writer, element); raptor_free_xml_element(element); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n"); el_name = raptor_new_qname(nstack, (const unsigned char*)"blah", NULL /* no attribute value - element */); base_uri_copy = base_uri ? raptor_uri_copy(base_uri) : NULL; element = raptor_new_xml_element(el_name, NULL, /* language */ base_uri_copy); attrs = (raptor_qname **)RAPTOR_CALLOC(qnamearray, 1, sizeof(raptor_qname*)); attrs[0] = raptor_new_qname(nstack, (const unsigned char*)"a", (const unsigned char*)"b" /* attribute value */); raptor_xml_element_set_attributes(element, attrs, 1); raptor_xml_writer_empty_element(xml_writer, element); raptor_xml_writer_cdata(xml_writer, (const unsigned char*)"\n"); raptor_free_xml_writer(xml_writer); raptor_free_xml_element(element); raptor_free_namespace(foo_ns); raptor_free_namespaces(nstack); raptor_free_uri(base_uri); offset = raptor_iostream_tell(iostr); #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Freeing iostream\n", program); #endif raptor_free_iostream(iostr); if(offset != OUT_BYTES_COUNT) { fprintf(stderr, "%s: I/O stream wrote %d bytes, expected %d\n", program, (int)offset, (int)OUT_BYTES_COUNT); fputs("[[", stderr); (void)fwrite(string, 1, string_len, stderr); fputs("]]\n", stderr); return 1; } if(!string) { fprintf(stderr, "%s: I/O stream failed to create a string\n", program); return 1; } string_len = strlen((const char*)string); if(string_len != offset) { fprintf(stderr, "%s: I/O stream created a string length %d, expected %d\n", program, (int)string_len, (int)offset); return 1; } #if RAPTOR_DEBUG > 1 fprintf(stderr, "%s: Made XML string of %d bytes\n", program, (int)string_len); fputs("[[", stderr); (void)fwrite(string, 1, string_len, stderr); fputs("]]\n", stderr); #endif raptor_free_memory(string); raptor_free_world(world); /* keep gcc -Wall happy */ return(0); }