mootXmlDoc.h
Go to the documentation of this file.
1 /* -*- Mode: C++ -*- */
2 
3 /*
4  libmoot : moocow's part-of-speech tagging library
5  Copyright (C) 2003-2005 by Bryan Jurish <moocow@cpan.org>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License as published by the Free Software Foundation; either
10  version 3 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 /*--------------------------------------------------------------------------
23  * File: mootXmlDoc.h
24  * Author: Bryan Jurish <moocow@cpan.org>
25  * Description: C++ wrapper for libxml2 tree-mode XML documents
26  *--------------------------------------------------------------------------*/
27 
32 #ifndef _MOOT_XML_DOC_H
33 #define _MOOT_XML_DOC_H
34 
35 #include <mootConfig.h>
36 
37 #ifdef MOOT_LIBXML_ENABLED
38 
39 #include <stdio.h>
40 #include <stdarg.h>
41 #include <assert.h>
42 
43 #include <libxml/parser.h>
44 #include <libxml/tree.h>
45 #include <libxml/xpath.h>
46 #include <libxml/xpathInternals.h>
47 #include <libxml/xmlIO.h>
48 
49 #include <string>
50 
51 namespace moot {
52 
53 /*----------------------------------------------------
54  * mootXPathQuery
55  */
57 class mootXPathQuery
58 {
59 public:
60  /*------------------------------------------
61  * XPathQuery: Data
62  */
63  std::string expr;
64  xmlXPathCompExprPtr cmp;
65  xmlXPathContextPtr ctx;
66  xmlXPathObjectPtr obj;
67  //xmlNodePtr *cur; ///< Current node (for iteration)
68  int idx;
69 
70 public:
71  /*------------------------------------------
72  * XPathQuery: Methods: Constructors
73  */
81  mootXPathQuery(const std::string &xpathExpr="", bool do_compile=false)
82  : expr(xpathExpr),
83  cmp(NULL),
84  ctx(NULL),
85  obj(NULL),
86  idx(0)
87  {
88  if (do_compile) compile();
89  };
90 
99  mootXPathQuery(const std::string &xpathExpr,
100  xmlDocPtr xml_doc,
101  xmlNodePtr ctx_node=NULL,
102  bool do_eval=false,
103  bool do_sort=false)
104  : expr(xpathExpr),
105  cmp(NULL),
106  ctx(NULL),
107  obj(NULL),
108  idx(0)
109  {
110  compile();
111  context(xml_doc,ctx_node);
112  if (do_eval) eval(do_sort);
113  };
114 
116  mootXPathQuery(const mootXPathQuery &q2)
117  : expr(q2.expr),
118  cmp(NULL),
119  ctx(NULL),
120  obj(NULL),
121  idx(0)
122  {};
123 
125  inline ~mootXPathQuery(void) { clear(); };
126 
128  inline void clear(void)
129  {
130  //expr.clear();
131  if (cmp) { xmlXPathFreeCompExpr(cmp); cmp = NULL; }
132  if (ctx) { xmlXPathFreeContext(ctx); ctx = NULL; }
133  if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
134  idx = 0;
135  };
137 
138  /*------------------------------------------*/
142  inline xmlXPathCompExprPtr compile(void)
143  {
144  clear();
145  cmp = xmlXPathCompile(BAD_CAST expr.c_str());
146  return cmp;
147  };
148 
150  inline xmlXPathContextPtr context(xmlDocPtr xml_doc, xmlNodePtr ctx_node=NULL)
151  {
152  idx = 0;
153  if (ctx) { xmlXPathFreeContext(ctx); ctx = NULL; }
154  if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
155  if (!cmp) return NULL;
156  ctx = xmlXPathNewContext(xml_doc);
157  if (ctx && ctx_node) ctx->node = ctx_node;
158  return ctx;
159  };
160 
166  inline xmlXPathObjectPtr eval(bool do_sort=false)
167  {
168  idx = 0;
169  if (obj) { xmlXPathFreeObject(obj); obj = NULL; }
170  if (!cmp || !ctx) return NULL;
171  obj = xmlXPathCompiledEval(cmp,ctx);
172  if (do_sort && obj && obj->nodesetval) xmlXPathNodeSetSort(obj->nodesetval);
173  return obj;
174  };
175 
184  inline xmlXPathObjectPtr eval(xmlDocPtr xml_doc,
185  xmlNodePtr ctx_node=NULL,
186  bool do_sort=false,
187  bool do_compile=false)
188  {
189  if (do_compile && !compile()) return NULL;
190  if (!context(xml_doc, ctx_node)) return NULL;
191  return eval(do_sort);
192  };
194 
195  /*------------------------------------------*/
202  inline xmlNodeSetPtr nodeset(void)
203  {
204  return (obj ? obj->nodesetval : NULL);
205  };
206 
208  inline int size(void)
209  {
210  return (obj && obj->nodesetval ? obj->nodesetval->nodeNr : 0);
211  };
212 
217  inline xmlNodePtr first(void)
218  {
219  idx = 0;
220  return cur();
221  };
222 
227  inline xmlNodePtr cur(void)
228  {
229  return (obj && obj->nodesetval && idx < obj->nodesetval->nodeNr
230  ? obj->nodesetval->nodeTab[idx]
231  : NULL);
232  };
233 
238  inline xmlNodePtr next(void)
239  {
240  return (obj && obj->nodesetval && ++idx < obj->nodesetval->nodeNr
241  ? obj->nodesetval->nodeTab[idx]
242  : NULL);
243  };
245 
246 }; //-- end class mootmootXPathQuery
247 
248 
249 /*--------------------------------------------------------------
250  * mootXmlDoc
251  */
253 class mootXmlDoc {
254 public:
255  /*----------------------------------------------------
256  * mootXmlDoc: Data
257  */
260  std::string srcname;
261 
262 
265  //-- libxml2 stuff
266  xmlDocPtr xml_doc;
267  int xml_options;
268  bool xml_format;
269 
270 
271  public:
274  /*----------------------------------------------------
275  * mootXmlDoc: Constructor
276  */
278  mootXmlDoc(const std::string &myname = "(unknown)",
279  int parse_options = 0,
280  bool do_format = false)
281  : srcname(myname),
282  xml_doc(NULL),
283  xml_options(parse_options),
284  xml_format(do_format)
285  {
286  //-- libxml2 sanity check
287  LIBXML_TEST_VERSION ;
288  };
289 
290  /*----------------------------------------------------
291  * mootXmlDoc: Destructor
292  */
294  virtual ~mootXmlDoc(void)
295  {
296  reset();
297  srcname.clear();
298  };
299 
300  /*----------------------------------------------------
301  * mootXmlDoc: Reset
302  */
304  virtual void reset(void)
305  {
306  if (xml_doc) xmlFreeDoc(xml_doc);
307  xml_doc = NULL;
308  };
310 
311  /*----------------------------------------------------*/
318  virtual bool loadFilename(const char *filename_or_url, const char *encoding=NULL);
319 
328  virtual bool loadFile(FILE * file,
329  const char * encoding =NULL,
330  const char * base_url =NULL,
331  const std::string& myname ="");
332 
341  virtual bool loadBuffer(const char* buffer,
342  int bufsize,
343  const char* base_url = NULL,
344  const char* encoding = NULL,
345  const std::string& myname ="");
346 
348  virtual bool _pre_load_hook(void) { return true; };
349 
351  virtual bool _post_load_hook(void) { return true; };
353 
354 
355 
356  /*----------------------------------------------------*/
366  virtual bool saveFilename(const char *filename_or_url,
367  const char *encoding=NULL,
368  int compressMode=-1);
369 
376  virtual bool saveFile(FILE *file, const char *encoding=NULL);
377 
386  virtual bool saveBuffer(xmlChar **buffer_ptr,
387  int *buflen,
388  const char *encoding=NULL);
389 
391  virtual bool _pre_save_hook(void) { return true; };
392 
394  virtual bool _post_save_hook(void) { return true; };
396 
397  /*----------------------------------------------------*/
404  inline xmlNodePtr root(void)
405  {
406  return xml_doc ? xmlDocGetRootElement(xml_doc) : NULL;
407  };
408 
413  inline xmlDocPtr document(void)
414  {
415  return xml_doc ? xml_doc : (xml_doc = xmlNewDoc(BAD_CAST "1.0")); // (version)
416  };
417 
424  inline xmlNodePtr addNewNode(xmlNodePtr parent, const char *name)
425  {
426  xmlNodePtr node = xmlNewNode(NULL, BAD_CAST name); // (ns,name)
427  assert(node != NULL);
428 
429  if (parent == NULL) {
430  //-- no parent: try root node
431  parent = root();
432  if (parent == NULL) {
433  //-- still no parent: add a new root node
434  xmlDocSetRootElement(document(), node);
435  return node;
436  }
437  }
438  return xmlAddChild(parent,node);
439  };
440 
446  static inline xmlNodePtr addNewText(xmlNodePtr parent, const char *text)
447  {
448  assert(parent != NULL);
449  xmlNodePtr node = xmlNewText(BAD_CAST text); // (content)
450  assert(node != NULL);
451  return xmlAddChild(parent, node);
452  };
453 
460  inline xmlNodePtr addComment(xmlNodePtr parent, const char *text)
461  {
462  if (parent == NULL) {
463  //-- no parent: add root comment
464  return xmlNewDocComment(document(), BAD_CAST text);
465  }
466  //-- parent given: create and add new node under parent
467  xmlNodePtr cmt = xmlNewComment(BAD_CAST text);
468  assert(cmt != NULL);
469  return xmlAddChild(parent, cmt);
470  };
471 
472 
477  static inline void addContent(xmlNodePtr node, const char *content)
478  {
479  assert(node != NULL);
480  xmlNodeAddContent(node, BAD_CAST content);
481  };
482 
487  static inline void setContent(xmlNodePtr node, const char *content)
488  {
489  assert(node != NULL);
490  xmlNodeSetContent(node, BAD_CAST content);
491  };
492 
497  static inline xmlAttrPtr hasProp(xmlNodePtr node, const char *name)
498  {
499  assert(node != NULL);
500  return xmlHasProp(node, BAD_CAST name);
501  };
502 
509  static inline std::string getProp(xmlNodePtr node, const char *name)
510  {
511  assert(node != NULL);
512  xmlChar *v = xmlGetProp(node, BAD_CAST name);
513  std::string s="";
514  if (v) {
515  s = (const char *)v;
516  xmlFree(v);
517  }
518  return s;
519  };
520 
525  static inline xmlAttrPtr setProp(xmlNodePtr node,
526  const char *name,
527  const char *value)
528  {
529  assert(node != NULL);
530  return xmlSetProp(node, BAD_CAST name, BAD_CAST value);
531  };
532 
539  static inline std::string attrValue(xmlAttrPtr attr_node)
540  {
541  assert(attr_node != NULL && attr_node->type == XML_ATTRIBUTE_NODE);
542  return std::string(attr_node->children != NULL && attr_node->children->content != NULL
543  ? (const char *)attr_node->children->content
544  : "");
545  };
547 
548  /*----------------------------------------------------*/
561  virtual mootXPathQuery *xpath(const std::string &xpathExpr,
562  xmlNodePtr ctx_node=NULL,
563  bool do_eval=false,
564  bool do_sort=false)
565  {
566  mootXPathQuery *xpq = new mootXPathQuery(xpathExpr);
567  if (!xpq->compile()) {
568  carp("could not compile XPath expression `%s'\n", xpq->expr.c_str());
569  delete xpq;
570  return NULL;
571  }
572  else if (!xpq->context(xml_doc, ctx_node ? ctx_node : root())) {
573  carp("could not initialize XPath context for `%s'\n", xpq->expr.c_str());
574  delete xpq;
575  return NULL;
576  }
577  else if (do_eval && !xpq->eval(do_sort)) {
578  carp("could not evaluate XPath query `%s'\n", xpq->expr.c_str());
579  delete xpq;
580  return NULL;
581  }
582  return xpq;
583  };
585 
586 
587  /*----------------------------------------------------*/
591  virtual void carp(char *fmt, ...)
592  {
593  fprintf(stderr, "mootXmlDoc: ");
594  va_list ap;
595  va_start(ap, fmt);
596  vfprintf(stderr, fmt, ap);
597  va_end(ap);
598  };
600 };
601 
602 
603 }; /* moot_END_NAMESPACE */
604 
605 #endif /* MOOT_LIBXML_ENABLED */
606 
607 #endif /* MOOT_XML_DOC_H */
608 
Definition: mootAssocVector.h:39
safely includes autoheader preprocessor macros