#include #include #include #include #include #include #include #include const char XMLDocument[] = "\n \ \n \ \n \ \n \ mighty_command \n \ value1 \n \ value2 \n \ value3 \n \ value4 \n \ \n"; const char XMLDocumentDTD[] = " \n \ \n \ \n \ \n \ "; namespace string_algo { #if defined WINDOWS inline int vsnprintf(char * Str, size_t Size, const char * Format, va_list Args) { return _vsnprintf(Str, Size, Format, Args); } #endif std::string sprintf(const char * Format, va_list Args) { std::vector Buffer(1024); while (vsnprintf(&Buffer[0], Buffer.size(), Format, Args) == -1) Buffer.resize(2 * Buffer.size()); return std::string(&Buffer[0]); } } void ErrorHandler (void * Ctx, const char * Msg, ...) { va_list Args; va_start(Args, Msg); std::string ErrorMsg = string_algo::sprintf(Msg, Args); if ((! ErrorMsg.empty()) && (ErrorMsg[ErrorMsg.size() - 1] == '\n')) ErrorMsg.erase(ErrorMsg.size() - 1, 1); if (Ctx) std::cerr << "libxml -> " << "[" << reinterpret_cast(Ctx)->_private << "]" << ErrorMsg << std::endl; else std::cerr << "libxml -> " << "[" << Ctx << "]" << ErrorMsg << std::endl; } void example1Func() { xmlParserCtxtPtr ctxt; xmlDocPtr doc; ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { std::cerr << "Failed to allocate parser context" << std::endl; return; } ctxt->_private = reinterpret_cast(0xF00BA4); ctxt->sax->error = ErrorHandler; ctxt->sax->warning = ErrorHandler; // parse the file doc = xmlCtxtReadMemory( ctxt, XMLDocument, std::strlen(XMLDocument), "example.xml", NULL, /*XML_PARSE_DTDVALID | */XML_PARSE_NONET ); // check if parsing suceeded if (doc == NULL) { std::cerr << "[0] Failed to parse" << std::endl; } else { // check if validation suceeded if (ctxt->valid == 0) std::cerr << "[1] Failed to validate" << std::endl; // validate xmlParserInputBufferPtr input = xmlParserInputBufferCreateMem( XMLDocumentDTD, std::strlen(XMLDocumentDTD), XML_CHAR_ENCODING_ASCII ); if (! input) std::cerr << "unable to create input buffer" << std::endl; xmlDtdPtr dtd = xmlIOParseDTD(ctxt->sax, input, XML_CHAR_ENCODING_ASCII); if (! dtd) std::cerr << "unable to parse DTD" << std::endl; ctxt->vctxt.userData = reinterpret_cast(ctxt); ctxt->vctxt.error = ErrorHandler; ctxt->vctxt.warning = ErrorHandler; if (! xmlValidateDtd(&ctxt->vctxt, doc, dtd)) std::cerr << "[2] Failed to validate" << std::endl; // TODO free input // TODO free dtd // print nodes, content and attributes xmlNodePtr pNode = xmlDocGetRootElement(doc); std::cout << "root node name: " << pNode->name << std::endl; for (pNode = pNode->children; pNode; pNode = pNode->next) { if (pNode->type != XML_ELEMENT_NODE) continue; if (pNode->name) std::cout << "Node: " << pNode->name << std::endl; xmlChar * String = xmlNodeGetContent(pNode); if (String) { std::cout << " - content: " << String << std::endl; xmlFree(String); }; } // free up the resulting document xmlFreeDoc(doc); } // free up the parser context xmlFreeParserCtxt(ctxt); } int main(int argc, char * argv[]) { printf("lib version %d\n", LIBXML_VERSION); printf("lib version %s\n", LIBXML_VERSION_STRING); assert(LIBXML_VERSION >= 20606); // >= 2.6.6 // xmlSetGenericErrorFunc(NULL, ErrorHandler); xmlCheckVersion(LIBXML_VERSION); example1Func(); // Cleanup function for the XML library. xmlCleanupParser(); }