UniSet  2.2.1
UniXML.h
См. документацию.
00001 /* This file is part of the UniSet project
00002  * Copyright (c) 2002-2010 Free Software Foundation, Inc.
00003  * Copyright (c) 2002, 2009, 2010 Vitaly Lipatov
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 Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018  */
00019 // --------------------------------------------------------------------------
00026 // --------------------------------------------------------------------------
00027 
00028 // Класс для работы с данными в XML, выборки и перекодирования
00029 
00030 #ifndef UniXML_H_
00031 #define UniXML_H_
00032 
00033 #include <assert.h>
00034 #include <string>
00035 #include <cstddef>
00036 
00037 #include <libxml/parser.h>
00038 #include <libxml/tree.h>
00039 // --------------------------------------------------------------------------
00040 class UniXML_iterator:
00041     public std::iterator<std::bidirectional_iterator_tag, xmlNode, ptrdiff_t, xmlNode*, xmlNode&>
00042 {
00043     public:
00044         UniXML_iterator(xmlNode* node) :
00045             curNode(node)
00046         {}
00047         UniXML_iterator(): curNode(0) {}
00048 
00049         std::string getProp2( const std::string& name, const std::string& defval = "" );
00050         std::string getProp( const std::string& name );
00051         std::string getPropUtf8( const std::string& name );
00052         int getIntProp( const std::string& name );
00054         int getPIntProp( const std::string& name, int def );
00055         void setProp( const std::string& name, const std::string& text );
00056 
00057         bool findName( const std::string& node, const std::string& searchname, bool deepfind = true );
00058         bool find( const std::string& searchnode, bool deepfind = true);
00059         xmlNode* findX( xmlNode* root, const std::string& searchnode, bool deepfind = true );
00060 
00062         bool goNext();
00063 
00065         bool goThrowNext();
00066 
00068         bool goPrev();
00069 
00070         bool canPrev();
00071         bool canNext();
00072 #if 0
00073         friend inline bool operator==(const UniXML_iterator& lhs, const UniXML_iterator& rhs)
00074         {
00075             return ( lhs.curNode != 0 && rhs.curNode != 0 && lhs.curNode == rhs.curNode );
00076         }
00077 
00078         friend inline bool operator!=(const UniXML_iterator& lhs, const UniXML_iterator& rhs)
00079         {
00080             return !(lhs == rhs);
00081         }
00082 
00083         inline bool operator==(int a)
00084         {
00085             if( a == 0 )
00086                 return (curNode == NULL);
00087 
00088             return false;
00089         }
00090 #endif
00091         // Перейти к следующему узлу
00092         UniXML_iterator& operator+(int);
00093         UniXML_iterator& operator++(int);
00094         UniXML_iterator& operator+=(int);
00095         UniXML_iterator& operator++();
00096 
00097         // Перейти к предыдущему узлу
00098         UniXML_iterator& operator-(int);
00099         UniXML_iterator& operator--(int);
00100         UniXML_iterator& operator--();
00101         UniXML_iterator& operator-=(int);
00102 
00106         bool goParent();
00107 
00111         bool goChildren();
00112 
00113         // Получить текущий узел
00114         xmlNode* getCurrent()
00115         {
00116             return curNode;
00117         }
00118 
00119         // Получить название текущего узла
00120         inline const std::string getName() const
00121         {
00122             if( curNode )
00123             {
00124                 if( !curNode->name )
00125                     return "";
00126 
00127                 return (char*) curNode->name;
00128             }
00129 
00130             return "";
00131         }
00132 
00133         const std::string getContent() const;
00134 
00135         inline operator xmlNode* () const
00136         {
00137             //ulog.< "current\n";
00138             return curNode;
00139         }
00140 
00141         inline void goBegin()
00142         {
00143             while(canPrev())
00144             {
00145                 goPrev();
00146             }
00147         }
00148 
00149         inline void goEnd()
00150         {
00151             while(canNext())
00152             {
00153                 goNext();
00154             }
00155         }
00156 
00157     protected:
00158         xmlNode* curNode;
00159 };
00160 // --------------------------------------------------------------------------
00161 class UniXML
00162 {
00163     public:
00164 
00165         typedef UniXML_iterator iterator;
00166 
00167         inline xmlNode* getFirstNode()
00168         {
00169             return xmlDocGetRootElement(doc);
00170         }
00171 
00172         inline xmlNode* getFirstNode() const
00173         {
00174             return xmlDocGetRootElement(doc);
00175         }
00176 
00177 
00179         inline iterator begin()
00180         {
00181             return iterator(getFirstNode());
00182         }
00183 
00184         inline iterator end()
00185         {
00186             return  iterator(NULL);
00187         }
00188 
00189         // Загружает указанный файл
00190         void open(const std::string& filename);
00191 
00192         void close();
00193         inline bool isOpen()
00194         {
00195             return doc != 0;
00196         }
00197         UniXML( const std::string& filename );
00198 
00199         UniXML();
00200 
00201         ~UniXML();
00202 
00203         xmlDoc* doc;
00204         inline std::string getFileName()
00205         {
00206             return filename;
00207         }
00208 
00209         // Создать новый XML-документ
00210         void newDoc(const std::string& root_node, std::string xml_ver = "1.0");
00211 
00212         // Получить свойство name указанного узла node
00213         static std::string getProp(const xmlNode* node, const std::string& name);
00214         static std::string getProp2(const xmlNode* node, const std::string& name, const std::string& defval = "" );
00215 
00216         static std::string getPropUtf8(const xmlNode* node, const std::string& name);
00217         static int getIntProp(const xmlNode* node, const std::string& name);
00219         static int getPIntProp(const xmlNode* node, const std::string& name, int def);
00220 
00221         // Установить свойство name указанного узла node
00222         static void setProp(xmlNode* node, const std::string& name, const std::string& text);
00223 
00224         // Добавить новый дочерний узел
00225         static xmlNode* createChild(xmlNode* node, const std::string& title, const std::string& text);
00226 
00227         // Добавить следующий узел
00228         static xmlNode* createNext(xmlNode* node, const std::string& title, const std::string& text);
00229 
00230         // Удалить указанный узел и все вложенные узлы
00231         static void removeNode(xmlNode* node);
00232 
00233         // копировать указанный узел и все вложенные узлы
00234         static xmlNode* copyNode(xmlNode* node, int recursive = 1);
00235 
00236         // Сохранить в файл, если параметр не указан, сохраняет в тот файл
00237         // который был загружен последним.
00238         bool save(const std::string& filename = "", int level = 2);
00239 
00240         // Переместить указатель к следующему узлу
00241         static xmlNode* nextNode(xmlNode* node);
00242 
00243         // После проверки исправить рекурсивный алгоритм на обычный,
00244         // используя ->parent
00245         xmlNode* findNode( xmlNode* node, const std::string& searchnode, const std::string& name = "") const;
00246         xmlNode* findNodeUtf8( xmlNode* node, const std::string& searchnode, const std::string& name = "") const;
00247 
00248         // ??
00249         //width means number of nodes of the same level as node in 1-st parameter (width number includes first node)
00250         //depth means number of times we can go to the children, if 0 we can't go only to elements of the same level
00251         xmlNode* extFindNode( xmlNode* node, int depth, int width, const std::string& searchnode, const std::string& name = "", bool top = true ) const;
00252         xmlNode* extFindNodeUtf8( xmlNode* node, int depth, int width, const std::string& searchnode, const std::string& name = "", bool top = true ) const;
00253 
00254 
00255     protected:
00256         std::string filename;
00257 
00258         // Преобразование текстовой строки из XML в строку нашего внутреннего представления
00259         static std::string xml2local( const std::string& text );
00260 
00261         // Преобразование текстовой строки из нашего внутреннего представления в строку для XML
00262         // Возвращает указатель на временный буфер, который один на все вызовы функции.
00263         static const xmlChar* local2xml( const std::string& text );
00264         static std::string local2utf8( const std::string& text );
00265 
00266         static int recur;
00267 };
00268 // --------------------------------------------------------------------------
00269 #endif