XMLNodeIterator.h

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                                                                      |
00003 |                      __   __    ____ _____ ____                      |
00004 |                      \ \ / /_ _/ ___|_   _|___ \                     |
00005 |                       \ V / _` \___ \ | |   __) |                    |
00006 |                        | | (_| |___) || |  / __/                     |
00007 |                        |_|\__,_|____/ |_| |_____|                    |
00008 |                                                                      |
00009 |                               core system                            |
00010 |                                                        (C) SuSE GmbH |
00011 \----------------------------------------------------------------------/
00012 
00013   File:       XMLNodeIterator.h
00014 
00015   Author:     Michael Radziej <mir@suse.de>
00016   Maintainer: Michael Radziej <mir@suse.de>
00017 
00018   Purpose: Provides an iterator interface for XML files
00019 
00020 */
00021 
00022 #ifndef XMLNodeIterator_h
00023 #define XMLNodeIterator_h
00024 
00025 #include <y2util/LibXMLHelper.h>
00026 // #include <libxml/debugXML.h>
00027 #include <iostream>
00028 #include <ostream>
00029 #include <sstream>
00030 #include <cassert>
00031 #include <iterator>
00032 
00033 extern "C" {
00034   typedef void * xmlTextReaderLocatorPtr;
00035   struct _xmlNode;
00036   typedef struct _xmlNode xmlNode;
00037   typedef xmlNode *xmlNodePtr;
00038 
00039   struct _xmlTextReader;
00040   typedef _xmlTextReader xmlTextReader;
00041   typedef xmlTextReader *xmlTextReaderPtr;
00042 
00043   struct _xmlError;
00044   typedef _xmlError xmlError;
00045   typedef xmlError *xmlErrorPtr;
00046 }
00047 
00048 
00049 
00050 
00054 class XMLParserError {
00055 public:
00059   XMLParserError(const char *msg,
00060                  int severity,
00061                  xmlTextReaderLocatorPtr locator,
00062                  int docLine,
00063                  int docColumn) throw();
00064 
00065   ~XMLParserError() throw();
00066 
00070   std::string msg() const throw();
00071 
00075   int severity() const throw();
00076 
00080   xmlTextReaderLocatorPtr locator() const throw();
00081 
00085   int docLine() const throw();
00086 
00090   int docColumn() const throw();
00091 
00096   std::string position() const throw();
00097 
00098 private:
00099 
00100   std::string _msg;
00101   int _severity;
00102   xmlTextReaderLocatorPtr _locator;
00103   int _docLine;
00104   int _docColumn;
00105 };
00106 
00107 
00108 std::ostream& operator<<(std::ostream &out, const XMLParserError& error);
00109 
00110 
00111 
00141 class XMLNodeIteratorBase {
00142 public:
00149   XMLNodeIteratorBase(std::istream &input, 
00150                       const std::string &baseUrl,
00151                       const char *validationPath = 0);
00152 
00158   XMLNodeIteratorBase();
00159 
00163   virtual ~XMLNodeIteratorBase();
00164 
00170   bool atEnd() const;
00171 
00180   bool 
00181   operator==(const XMLNodeIteratorBase &other) const;
00182 
00188   bool 
00189   operator!=(const XMLNodeIteratorBase &otherNode) const
00190   {
00191     return ! operator==(otherNode);
00192   }
00193 
00200   const XMLParserError *
00201   errorStatus() const;
00202 
00203 protected:
00204 
00216   virtual bool
00217   isInterested(const xmlNodePtr nodePtr) = 0;
00218   
00232   virtual void
00233   _process(const xmlTextReaderPtr readerPtr) = 0;
00234   
00238   void fetchNext();
00239 
00250   static void
00251   errorHandler(void * arg,
00252                const char * msg,
00253                int severity,
00254                xmlTextReaderLocatorPtr locator);
00255 
00256   
00257   virtual void setCurrent(const void *data) = 0;
00258   virtual void* getCurrent() const = 0;
00259 
00260 private:
00261 
00266   XMLNodeIteratorBase & operator=(const XMLNodeIteratorBase& otherNode);
00267 
00276   XMLNodeIteratorBase(const XMLNodeIteratorBase& otherNode);
00277 
00281   std::auto_ptr<XMLParserError> _error;
00282 
00287   std::istream* _input;
00288   
00292   xmlTextReaderPtr _reader;
00293 
00297   std::string _baseUrl;
00298 }; /* end class XMLNodeIteratorBase */
00299 
00300 
00301 
00302 /* --------------------------------------------------------------------------- */
00303 
00304 template <class ENTRYTYPE>
00305 class XMLNodeIterator : public XMLNodeIteratorBase,
00306                         public std::iterator<std::input_iterator_tag, ENTRYTYPE>  {
00307 public:
00314   XMLNodeIterator(std::istream &input,
00315                   const std::string &baseUrl,
00316                   const char *validationPath = 0)
00317     : XMLNodeIteratorBase(input, baseUrl, validationPath), _current(0)
00318   {
00319     /* Derived classes must call fetchNext() in their constructors themselves,
00320        XMLNodeIterator has no access to their virtual functions during
00321        construction */
00322   }
00323   
00324   
00332   XMLNodeIterator(ENTRYTYPE &entry)
00333     : XMLNodeIteratorBase()
00334   { 
00335     setCurrent((void *)& entry);
00336   }
00337   
00343   XMLNodeIterator()
00344     : XMLNodeIteratorBase(), _current(0)
00345   { }
00346   
00350   virtual ~XMLNodeIterator()
00351   { }
00352   
00357   ENTRYTYPE &
00358     operator*() const
00359   {
00360     assert (! atEnd());
00361     return * (ENTRYTYPE *) getCurrent();
00362   }
00363   
00368   ENTRYTYPE *
00369     operator()() const
00370   {
00371     if (_error)
00372       return 0;
00373     else
00374       return getCurrent();
00375   }
00376   
00381   XMLNodeIterator<ENTRYTYPE> &  /* ++iter */
00382   operator++() {
00383     fetchNext();
00384     return *this;
00385   }
00386   
00394   XMLNodeIterator operator++(int)   /* iter++ */
00395   {
00396     assert (!atEnd());
00397     XMLNodeIterator<ENTRYTYPE> tmp(operator()());
00398     fetchNext();
00399     return tmp;
00400   }
00401   
00406   const ENTRYTYPE *
00407     operator->()
00408   {
00409     assert(! atEnd());
00410     return getCurrent();
00411   }
00412   
00413 protected:
00414   
00426   virtual bool
00427     isInterested(const xmlNodePtr nodePtr) = 0;
00428   
00443   virtual ENTRYTYPE
00444   process(const xmlTextReaderPtr readerPtr) = 0;
00445 
00446   void
00447   _process(const xmlTextReaderPtr readerPtr)
00448   {
00449     setCurrent(new ENTRYTYPE(process(readerPtr)));
00450   }
00451 
00452 private:
00453 
00454   void setCurrent(const void *data)
00455   {
00456     if (data)
00457       _current.reset(new ENTRYTYPE(* (ENTRYTYPE *) data));
00458     else
00459       _current.reset(0);
00460   }
00461 
00462   void *getCurrent() const
00463   {
00464     return _current.get();
00465   }
00466   
00473   std::auto_ptr<ENTRYTYPE> _current;
00474 }; /* end class XMLNodeIterator */
00475 
00476 
00477 #endif

Generated on Fri Jun 16 15:51:35 2006 for liby2util by  doxygen 1.4.6