xmlNode* htmlParseFragment(void *doc, void *buffer, int buffer_len, void *url, int options, void *error_buffer, int error_buffer_len) { xmlNode* root_element = NULL; xmlParserErrors errCode; errCode = xmlParseInNodeContext((xmlNodePtr)doc, buffer, buffer_len, options, &root_element); if (errCode != XML_ERR_OK) { char *c_error_buffer = (char*)error_buffer; snprintf(c_error_buffer, error_buffer_len, "xml fragemnt parsing error (xmlParserErrors):%d", errCode); return NULL; } return root_element; }
str BATXMLcontent(bat *ret, const bat *bid) { BAT *b, *bn; BUN p, q; BATiter bi; xmlDocPtr doc; xmlNodePtr root; size_t size = BUFSIZ; str buf = GDKmalloc(size); const char *err = OPERATION_FAILED; xmlBufferPtr xbuf; if (buf == NULL) throw(MAL,"xml.content",MAL_MALLOC_FAIL); if ((b = BATdescriptor(*bid)) == NULL) { GDKfree(buf); throw(MAL, "xml.content", INTERNAL_BAT_ACCESS); } doc = xmlParseMemory("<doc/>", 6); root = xmlDocGetRootElement(doc); prepareResult(bn, b, TYPE_xml, "content", GDKfree(buf)); bi = bat_iterator(b); xbuf = xmlBufferCreate(); BATloop(b, p, q) { const char *t = (const char *) BUNtail(bi, p); size_t len; xmlNodePtr elem; xmlParserErrors xerr; const xmlChar *s; if (strNil(t)) { bunfastapp(bn, str_nil); bn->T->nonil = 0; continue; } len = strlen(t); xerr = xmlParseInNodeContext(root, t, (int) len, 0, &elem); if (xerr != XML_ERR_OK) { err = XML_PARSE_ERROR; goto bunins_failed; } xmlNodeDump(xbuf, doc, elem, 0, 0); s = xmlBufferContent(xbuf); len = strlen((const char *) s); if (len + 2 >= size) { GDKfree(buf); size = len + 128; buf = GDKmalloc(size); if (buf == NULL) { err = MAL_MALLOC_FAIL; goto bunins_failed; } } buf[0] = 'C'; strcpy(buf + 1, (const char *) s); bunfastapp(bn, buf); xmlBufferEmpty(xbuf); xmlFreeNodeList(elem); } xmlBufferFree(xbuf); xmlFreeDoc(doc); GDKfree(buf); finalizeResult(ret, bn, b); return MAL_SUCCEED; bunins_failed: xmlBufferFree(xbuf); xmlFreeDoc(doc); if (buf != NULL) GDKfree(buf); BBPunfix(b->batCacheid); BBPunfix(bn->batCacheid); throw(MAL, "xml.document", "%s", err); }
str BATXMLxmltext(bat *ret, const bat *bid) { BAT *b, *bn; BUN p, q; BATiter bi; size_t size = 0; str buf = NULL; xmlDocPtr doc = NULL; xmlNodePtr elem; str content = NULL; const char *err = OPERATION_FAILED; if ((b = BATdescriptor(*bid)) == NULL) throw(MAL, "xml.text", INTERNAL_BAT_ACCESS); prepareResult(bn, b, TYPE_str, "text", (void) 0); bi = bat_iterator(b); BATloop(b, p, q) { const char *t = (const char *) BUNtail(bi, p); size_t len; if (strNil(t)) { bunfastapp(bn, t); bn->T->nonil = 0; continue; } len = strlen(t); switch (*t) { case 'D': { xmlDocPtr d = xmlParseMemory(t + 1, (int) (len - 1)); elem = xmlDocGetRootElement(d); content = (str) xmlNodeGetContent(elem); xmlFreeDoc(d); if (content == NULL) { err = MAL_MALLOC_FAIL; goto bunins_failed; } break; } case 'C': if (doc == NULL) doc = xmlParseMemory("<doc/>", 6); xmlParseInNodeContext(xmlDocGetRootElement(doc), t + 1, (int) (len - 1), 0, &elem); content = (str) xmlNodeGetContent(elem); xmlFreeNodeList(elem); if (content == NULL) { err = MAL_MALLOC_FAIL; goto bunins_failed; } break; case 'A': { str s; if (buf == NULL || size < len) { size = len + 128; if (buf != NULL) GDKfree(buf); buf = GDKmalloc(size); if (buf == NULL) { err = MAL_MALLOC_FAIL; goto bunins_failed; } } s = buf; t++; while (*t) { if (*t == '"' || *t == '\'') { char q = *t++; s += XMLunquotestring(&t, q, s); } t++; } *s = 0; break; } default: assert(*t == 'A' || *t == 'C' || *t == 'D'); bunfastapp(bn, str_nil); bn->T->nonil = 0; continue; } assert(content != NULL || buf != NULL); bunfastapp(bn, content != NULL ? content : buf); if (content != NULL) GDKfree(content); content = NULL; } finalizeResult(ret, bn, b); if (buf != NULL) GDKfree(buf); if (doc != NULL) xmlFreeDoc(doc); return MAL_SUCCEED; bunins_failed: BBPunfix(b->batCacheid); BBPunfix(bn->batCacheid); if (buf != NULL) GDKfree(buf); if (doc != NULL) xmlFreeDoc(doc); if (content != NULL) GDKfree(content); throw(MAL, "xml.text", "%s", err); }