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-2005 by Bryan Jurish <moocow@ling.uni-potsdam.de>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011    
00012    This library 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 GNU
00015    Lesser General Public License for more details.
00016    
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with this library; 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 Mon Sep 11 16:10:33 2006 for libmoot by doxygen1.2.18