xmlsomreader.h

00001 /**************************************************************************
00002 *   Copyright (C) 2004 by root                                            *
00003 *   root@aquiles                                                          *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU General Public License as published by  *
00007 *   the Free Software Foundation; either version 2 of the License, or     *
00008 *   (at your option) any later version.                                   *
00009 *                                                                         *
00010 *   This program is distributed in the hope that it will be useful,       *
00011 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013 *   GNU General Public License for more details.                          *
00014 *                                                                         *
00015 *   You should have received a copy of the GNU General Public License     *
00016 *   along with this program; if not, write to the                         *
00017 *   Free Software Foundation, Inc.,                                       *
00018 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019 ***************************************************************************/
00020 
00021 #ifndef XMLSOMReader_H
00022 #define XMLSOMReader_H
00023 
00024 #include <libxml/xmlreader.h>
00025 
00026 #include <stdlib.h>
00027 #include <string>
00028 #include <stdexcept>
00029 #include <map>
00030 
00031 using std::exception;
00032 
00033 namespace xmlsom {
00034 
00035 
00036   class XMLSOMReader {
00037   
00038     public:
00039   
00040       XMLSOMReader(std::string filename) throw(std::exception);
00041     
00042       ~XMLSOMReader() {};
00043           
00044     protected:    
00045     
00046       void doParse() throw(std::exception);    
00047     
00048       virtual void processElement( const std::string& name,
00049                                    const std::string& value,
00050                                    const std::map<std::string,std::string>& attrs )
00051         throw(exception) = 0;
00052                                 
00053       virtual void processEndElement(const std::string& name) {};
00054     
00055     private:
00056   
00057       void prepareNode();
00058     
00059       void prepareAttrs();
00060   
00061       xmlTextReaderPtr reader;
00062       
00063       std::string filename;  
00064 
00065       std::map<std::string,std::string> atribs;
00066 
00067       const xmlChar* name;
00068 
00069       const xmlChar* value;
00070 
00071       std::string sname;
00072 
00073       std::string svalue;
00074 
00075       bool handleEmptyElement;
00076   };
00077 
00078 
00079 
00080   //default constructor
00081   XMLSOMReader::XMLSOMReader(std::string fileName) throw(std::exception)
00082     : filename(fileName) { 
00083   
00084     reader = xmlNewTextReaderFilename(filename.data());
00085  
00086     if (reader == NULL)
00087       throw std::invalid_argument("Invalid filename path");
00088 
00089     handleEmptyElement = false;
00090   
00091   };
00092 
00093 
00094 
00095   //start point of parsing
00096   //must be called by subclasses
00097   void XMLSOMReader::doParse() throw (std::exception) {
00098 
00099     int ret = xmlTextReaderRead(reader);  
00100 
00101     //traverses the xml node tree
00102     while (ret == 1) {    
00103       //formats the node
00104       prepareNode();
00105     
00106       //read next node
00107       ret = xmlTextReaderRead(reader);
00108     }
00109 
00110     xmlFreeTextReader(reader);  
00111 
00112     if (ret != 0)
00113       throw std::invalid_argument("failed to parse " + filename);  
00114   };
00115 
00116 
00117 
00118   //formats the node for a aplication-specific processing class
00119   void XMLSOMReader::prepareNode() {
00120   
00121     //element type
00122     int nodeType = xmlTextReaderNodeType(reader);  
00123 
00124     switch(nodeType) {
00125 
00126       case XML_READER_TYPE_ELEMENT: {
00127 
00128         if (handleEmptyElement) {
00129           processElement(sname, "", atribs);
00130           handleEmptyElement = false;
00131         }
00132 
00133         name = xmlTextReaderConstName(reader);
00134         
00135         sname = std::string( (char*) name);
00136         
00137         //extracts the attributes into a map<string,string>
00138         prepareAttrs();
00139         
00140         handleEmptyElement = true;
00141 
00142         break;
00143       }
00144 
00145       
00146       case XML_READER_TYPE_TEXT: {
00147 
00148         value = xmlTextReaderConstValue(reader);
00149 
00150         if (value != NULL) {
00151           svalue = std::string( (char*) value );
00152         } else {
00153           svalue = "";
00154         }
00155 
00156         //delegates the processing for a subclass
00157         processElement(sname, svalue, atribs);      
00158         handleEmptyElement = false;
00159 
00160         break;
00161       }
00162 
00163 
00164       case XML_READER_TYPE_END_ELEMENT: {      
00165         processEndElement( sname );
00166         break;
00167       }
00168     }
00169   
00170   }
00171 
00172 
00173 
00174   // reads the attributes of a node generating a map
00175   // of name<->value pairs
00176   void XMLSOMReader::prepareAttrs() {  
00177   
00178     const xmlChar* name;
00179     const xmlChar* value;
00180   
00181     atribs.clear();
00182 
00183     int count = xmlTextReaderAttributeCount(reader);
00184 
00185     for(register int i = 0 ; i < count ; i++) {
00186   
00187       if (xmlTextReaderMoveToAttributeNo(reader, i) == 1) {
00188         name = xmlTextReaderConstName(reader);
00189         value = xmlTextReaderConstValue(reader);
00190 
00191         std::string sname( (char *) name );
00192         std::string svalue( (char *) value );
00193       
00194         //adds attribute pair
00195         atribs[sname] = svalue;
00196       
00197       }
00198     }
00199   };
00200 
00201 
00202 };
00203 
00204 #endif
00205 
00206 

Generated on Tue Aug 7 16:03:33 2007 for SOMCode by  doxygen 1.5.3