Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

mootXmlDoc.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*- */
00002 
00003 /*
00004    libmoot : moocow's part-of-speech tagging library
00005    Copyright (C) 2003-2004 by Bryan Jurish <moocow@ling.uni-potsdam.de>
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00020 */
00021 
00022 /*--------------------------------------------------------------------------
00023  * File: mootXmlDoc.h
00024  * Author: Bryan Jurish <moocow@ling.uni-potsdam.de>
00025  * Description: C++ wrapper for libxml2 tree-mode XML documents
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  * mootXPathQuery
00051  */
00053 class mootXPathQuery
00054 {
00055 public:
00056   /*------------------------------------------
00057    * XPathQuery: Data
00058    */
00059   std::string           expr; 
00060   xmlXPathCompExprPtr   cmp;  
00061   xmlXPathContextPtr    ctx;  
00062   xmlXPathObjectPtr     obj;  
00063   //xmlNodePtr           *cur;  ///< Current node (for iteration)
00064   int                   idx;  
00065 
00066 public:
00067   /*------------------------------------------
00068    * XPathQuery: Methods: Constructors
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     //expr.clear();
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 }; //-- end class mootmootXPathQuery
00243 
00244 
00245 /*--------------------------------------------------------------
00246  * mootXmlDoc
00247  */
00249 class mootXmlDoc {
00250 public:
00251   /*----------------------------------------------------
00252    * mootXmlDoc: Data
00253    */
00256   std::string srcname;         
00257 
00258 
00261   //-- libxml2 stuff
00262   xmlDocPtr  xml_doc;      
00263   int        xml_options;  
00264   bool       xml_format;   
00265 
00266  
00267  public:
00270   /*----------------------------------------------------
00271    * mootXmlDoc: Constructor
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     //-- libxml2 sanity check
00283     LIBXML_TEST_VERSION ;
00284   };
00285 
00286   /*----------------------------------------------------
00287    * mootXmlDoc: Destructor
00288    */
00290   virtual ~mootXmlDoc(void)
00291   {
00292     reset();
00293     srcname.clear();
00294   };
00295 
00296   /*----------------------------------------------------
00297    * mootXmlDoc: Reset
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")); // (version)
00412   };
00413 
00420   inline xmlNodePtr addNewNode(xmlNodePtr parent, const char *name)
00421   {
00422     xmlNodePtr node = xmlNewNode(NULL, BAD_CAST name); // (ns,name)
00423     assert(node != NULL);
00424 
00425     if (parent == NULL) {
00426       //-- no parent: try root node
00427       parent = root();
00428       if (parent == NULL) {
00429         //-- still no parent: add a new root node
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); // (content)
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       //-- no parent: add root comment
00460       return xmlNewDocComment(document(), BAD_CAST text);
00461     }
00462     //-- parent given: create and add new node under parent
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 }; /* moot_END_NAMESPACE */
00600 
00601 #endif /* MOOT_LIBXML_ENABLED */
00602 
00603 #endif /* MOOT_XML_DOC_H */
00604 

Generated on Wed Jul 28 15:48:03 2004 for libmoot by doxygen1.2.15