00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _MOOT_XML_DOC_H
00029 #define _MOOT_XML_DOC_H
00030
00031 #include <mootConfig.h>
00032
00033 #ifdef MOOT_LIBXML_ENABLED
00034
00035 #include <stdio.h>
00036 #include <stdarg.h>
00037 #include <assert.h>
00038
00039 #include <libxml/parser.h>
00040 #include <libxml/tree.h>
00041 #include <libxml/xpath.h>
00042 #include <libxml/xpathInternals.h>
00043 #include <libxml/xmlIO.h>
00044
00045 #include <string>
00046
00047 namespace moot {
00048
00049
00050
00051
00053 class mootXPathQuery
00054 {
00055 public:
00056
00057
00058
00059 std::string expr;
00060 xmlXPathCompExprPtr cmp;
00061 xmlXPathContextPtr ctx;
00062 xmlXPathObjectPtr obj;
00063
00064 int idx;
00065
00066 public:
00067
00068
00069
00077 mootXPathQuery(const std::string &xpathExpr="", bool do_compile=false)
00078 : expr(xpathExpr),
00079 cmp(NULL),
00080 ctx(NULL),
00081 obj(NULL),
00082 idx(0)
00083 {
00084 if (do_compile) compile();
00085 };
00086
00095 mootXPathQuery(const std::string &xpathExpr,
00096 xmlDocPtr xml_doc,
00097 xmlNodePtr ctx_node=NULL,
00098 bool do_eval=false,
00099 bool do_sort=false)
00100 : expr(xpathExpr),
00101 cmp(NULL),
00102 ctx(NULL),
00103 obj(NULL),
00104 idx(0)
00105 {
00106 compile();
00107 context(xml_doc,ctx_node);
00108 if (do_eval) eval(do_sort);
00109 };
00110
00112 mootXPathQuery(const mootXPathQuery &q2)
00113 : expr(q2.expr),
00114 cmp(NULL),
00115 ctx(NULL),
00116 obj(NULL),
00117 idx(0)
00118 {};
00119
00121 inline ~mootXPathQuery(void) { clear(); };
00122
00124 inline void clear(void)
00125 {
00126
00127 if (cmp) { xmlXPathFreeCompExpr(cmp); cmp = NULL; }
00128 if (ctx) { xmlXPathFreeContext(ctx); ctx = NULL; }
00129 if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
00130 idx = 0;
00131 };
00133
00134
00138 inline xmlXPathCompExprPtr compile(void)
00139 {
00140 clear();
00141 cmp = xmlXPathCompile(BAD_CAST expr.c_str());
00142 return cmp;
00143 };
00144
00146 inline xmlXPathContextPtr context(xmlDocPtr xml_doc, xmlNodePtr ctx_node=NULL)
00147 {
00148 idx = 0;
00149 if (ctx) { xmlXPathFreeContext(ctx); ctx = NULL; }
00150 if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
00151 if (!cmp) return NULL;
00152 ctx = xmlXPathNewContext(xml_doc);
00153 if (ctx && ctx_node) ctx->node = ctx_node;
00154 return ctx;
00155 };
00156
00162 inline xmlXPathObjectPtr eval(bool do_sort=false)
00163 {
00164 idx = 0;
00165 if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
00166 if (!cmp || !ctx) return NULL;
00167 obj = xmlXPathCompiledEval(cmp,ctx);
00168 if (do_sort && obj && obj->nodesetval) xmlXPathNodeSetSort(obj->nodesetval);
00169 return obj;
00170 };
00171
00180 inline xmlXPathObjectPtr eval(xmlDocPtr xml_doc,
00181 xmlNodePtr ctx_node=NULL,
00182 bool do_sort=false,
00183 bool do_compile=false)
00184 {
00185 if (do_compile && !compile()) return NULL;
00186 if (!context(xml_doc, ctx_node)) return NULL;
00187 return eval(do_sort);
00188 };
00190
00191
00198 inline xmlNodeSetPtr nodeset(void)
00199 {
00200 return (obj ? obj->nodesetval : NULL);
00201 };
00202
00204 inline int size(void)
00205 {
00206 return (obj && obj->nodesetval ? obj->nodesetval->nodeNr : 0);
00207 };
00208
00213 inline xmlNodePtr first(void)
00214 {
00215 idx = 0;
00216 return cur();
00217 };
00218
00223 inline xmlNodePtr cur(void)
00224 {
00225 return (obj && obj->nodesetval && idx < obj->nodesetval->nodeNr
00226 ? obj->nodesetval->nodeTab[idx]
00227 : NULL);
00228 };
00229
00234 inline xmlNodePtr next(void)
00235 {
00236 return (obj && obj->nodesetval && ++idx < obj->nodesetval->nodeNr
00237 ? obj->nodesetval->nodeTab[idx]
00238 : NULL);
00239 };
00241
00242 };
00243
00244
00245
00246
00247
00249 class mootXmlDoc {
00250 public:
00251
00252
00253
00256 std::string srcname;
00257
00258
00261
00262 xmlDocPtr xml_doc;
00263 int xml_options;
00264 bool xml_format;
00265
00266
00267 public:
00270
00271
00272
00274 mootXmlDoc(const std::string &myname = "(unknown)",
00275 int parse_options = 0,
00276 bool do_format = false)
00277 : srcname(myname),
00278 xml_doc(NULL),
00279 xml_options(parse_options),
00280 xml_format(do_format)
00281 {
00282
00283 LIBXML_TEST_VERSION ;
00284 };
00285
00286
00287
00288
00290 virtual ~mootXmlDoc(void)
00291 {
00292 reset();
00293 srcname.clear();
00294 };
00295
00296
00297
00298
00300 virtual void reset(void)
00301 {
00302 if (xml_doc) xmlFreeDoc(xml_doc);
00303 xml_doc = NULL;
00304 };
00306
00307
00314 virtual bool loadFilename(const char *filename_or_url, const char *encoding=NULL);
00315
00324 virtual bool loadFile(FILE * file,
00325 const char * encoding =NULL,
00326 const char * base_url =NULL,
00327 const std::string& myname ="");
00328
00337 virtual bool loadBuffer(const char* buffer,
00338 int bufsize,
00339 const char* base_url = NULL,
00340 const char* encoding = NULL,
00341 const std::string& myname ="");
00342
00344 virtual bool _pre_load_hook(void) { return true; };
00345
00347 virtual bool _post_load_hook(void) { return true; };
00349
00350
00351
00352
00362 virtual bool saveFilename(const char *filename_or_url,
00363 const char *encoding=NULL,
00364 int compressMode=-1);
00365
00372 virtual bool saveFile(FILE *file, const char *encoding=NULL);
00373
00382 virtual bool saveBuffer(xmlChar **buffer_ptr,
00383 int *buflen,
00384 const char *encoding=NULL);
00385
00387 virtual bool _pre_save_hook(void) { return true; };
00388
00390 virtual bool _post_save_hook(void) { return true; };
00392
00393
00400 inline xmlNodePtr root(void)
00401 {
00402 return xml_doc ? xmlDocGetRootElement(xml_doc) : NULL;
00403 };
00404
00409 inline xmlDocPtr document(void)
00410 {
00411 return xml_doc ? xml_doc : (xml_doc = xmlNewDoc(BAD_CAST "1.0"));
00412 };
00413
00420 inline xmlNodePtr addNewNode(xmlNodePtr parent, const char *name)
00421 {
00422 xmlNodePtr node = xmlNewNode(NULL, BAD_CAST name);
00423 assert(node != NULL);
00424
00425 if (parent == NULL) {
00426
00427 parent = root();
00428 if (parent == NULL) {
00429
00430 xmlDocSetRootElement(document(), node);
00431 return node;
00432 }
00433 }
00434 return xmlAddChild(parent,node);
00435 };
00436
00442 static inline xmlNodePtr addNewText(xmlNodePtr parent, const char *text)
00443 {
00444 assert(parent != NULL);
00445 xmlNodePtr node = xmlNewText(BAD_CAST text);
00446 assert(node != NULL);
00447 return xmlAddChild(parent, node);
00448 };
00449
00456 inline xmlNodePtr addComment(xmlNodePtr parent, const char *text)
00457 {
00458 if (parent == NULL) {
00459
00460 return xmlNewDocComment(document(), BAD_CAST text);
00461 }
00462
00463 xmlNodePtr cmt = xmlNewComment(BAD_CAST text);
00464 assert(cmt != NULL);
00465 return xmlAddChild(parent, cmt);
00466 };
00467
00468
00473 static inline void addContent(xmlNodePtr node, const char *content)
00474 {
00475 assert(node != NULL);
00476 xmlNodeAddContent(node, BAD_CAST content);
00477 };
00478
00483 static inline void setContent(xmlNodePtr node, const char *content)
00484 {
00485 assert(node != NULL);
00486 xmlNodeSetContent(node, BAD_CAST content);
00487 };
00488
00493 static inline xmlAttrPtr hasProp(xmlNodePtr node, const char *name)
00494 {
00495 assert(node != NULL);
00496 return xmlHasProp(node, BAD_CAST name);
00497 };
00498
00505 static inline std::string getProp(xmlNodePtr node, const char *name)
00506 {
00507 assert(node != NULL);
00508 xmlChar *v = xmlGetProp(node, BAD_CAST name);
00509 std::string s="";
00510 if (v) {
00511 s = (const char *)v;
00512 xmlFree(v);
00513 }
00514 return s;
00515 };
00516
00521 static inline xmlAttrPtr setProp(xmlNodePtr node,
00522 const char *name,
00523 const char *value)
00524 {
00525 assert(node != NULL);
00526 return xmlSetProp(node, BAD_CAST name, BAD_CAST value);
00527 };
00528
00535 static inline std::string attrValue(xmlAttrPtr attr_node)
00536 {
00537 assert(attr_node != NULL && attr_node->type == XML_ATTRIBUTE_NODE);
00538 return std::string(attr_node->children != NULL && attr_node->children->content != NULL
00539 ? (const char *)attr_node->children->content
00540 : "");
00541 };
00543
00544
00557 virtual mootXPathQuery *xpath(const std::string &xpathExpr,
00558 xmlNodePtr ctx_node=NULL,
00559 bool do_eval=false,
00560 bool do_sort=false)
00561 {
00562 mootXPathQuery *xpq = new mootXPathQuery(xpathExpr);
00563 if (!xpq->compile()) {
00564 carp("could not compile XPath expression `%s'\n", xpq->expr.c_str());
00565 delete xpq;
00566 return NULL;
00567 }
00568 else if (!xpq->context(xml_doc, ctx_node ? ctx_node : root())) {
00569 carp("could not initialize XPath context for `%s'\n", xpq->expr.c_str());
00570 delete xpq;
00571 return NULL;
00572 }
00573 else if (do_eval && !xpq->eval(do_sort)) {
00574 carp("could not evaluate XPath query `%s'\n", xpq->expr.c_str());
00575 delete xpq;
00576 return NULL;
00577 }
00578 return xpq;
00579 };
00581
00582
00583
00587 virtual void carp(char *fmt, ...)
00588 {
00589 fprintf(stderr, "mootXmlDoc: ");
00590 va_list ap;
00591 va_start(ap, fmt);
00592 vfprintf(stderr, fmt, ap);
00593 va_end(ap);
00594 };
00596 };
00597
00598
00599 };
00600
00601 #endif
00602
00603 #endif
00604