00001 /**************************************************************************** 00002 * VCGLib o o * 00003 * Visual and Computer Graphics Library o o * 00004 * _ O _ * 00005 * Copyright(C) 2004-2008 \/)\/ * 00006 * Visual Computing Lab /\/| * 00007 * ISTI - Italian National Research Council | * 00008 * \ * 00009 * All rights reserved. * 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This program is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 00020 * for more details. * 00021 * * 00022 ****************************************************************************/ 00023 #ifndef _XML_DOCUMENT_MANAGING_H 00024 #define _XML_DOCUMENT_MANAGING_H 00025 00026 #include <vector> 00027 #include <set> 00028 #include <QtXml/QDomDocument> 00029 #include<QtCore/QFile> 00030 #include<QtCore/QVector> 00031 #include <QtXml/QXmlStreamWriter> 00032 #include <QtCore/QString> 00033 00034 class XMLTag 00035 { 00036 public: 00037 typedef std::pair<QString,QString> TagAttribute; 00038 typedef QVector<TagAttribute> TagAttributes; 00039 QString _tagname; 00040 TagAttributes _attributes; 00041 00042 XMLTag(const QString& tagname = QString(),const TagAttributes& attr = TagAttributes()) 00043 :_tagname(tagname),_attributes(attr) 00044 { 00045 } 00046 00047 virtual ~XMLTag() 00048 { 00049 } 00050 }; 00051 00052 class XMLLeafTag : public XMLTag 00053 { 00054 public: 00055 QVector<QString> _text; 00056 00057 XMLLeafTag(const QString& tagname = QString(),const QVector<QString>& text = QVector<QString>()) 00058 :XMLTag(tagname),_text(text) 00059 { 00060 } 00061 00062 virtual ~XMLLeafTag() 00063 { 00064 } 00065 }; 00066 00067 class XMLDocumentWriter; 00068 00069 class XMLVisitor; 00070 00071 class XMLNode 00072 { 00073 public: 00074 XMLNode(XMLTag* tag); 00075 virtual ~XMLNode(); 00076 00077 virtual void applyProcedure(XMLVisitor& v) = 0; 00078 00079 XMLTag* _tag; 00080 }; 00081 00082 class XMLInteriorNode : public XMLNode 00083 { 00084 public: 00085 XMLInteriorNode(XMLTag* tag); 00086 00087 XMLNode* son(int ii); 00088 00089 QVector< XMLNode* > sons(); 00090 00091 void applyProcedure(XMLVisitor& v); 00092 00093 ~XMLInteriorNode(); 00094 00095 QVector< XMLNode* > _sons; 00096 }; 00097 00098 class XMLLeafNode : public XMLNode 00099 { 00100 public: 00101 XMLLeafNode(XMLLeafTag* leaftag); 00102 00103 void applyProcedure(XMLVisitor& v); 00104 virtual ~XMLLeafNode(); 00105 }; 00106 00107 class XMLDocument 00108 { 00109 public: 00110 XMLDocument(XMLInteriorNode* root) 00111 :_root(root) 00112 { 00113 } 00114 00115 ~XMLDocument() 00116 { 00117 delete (_root); 00118 } 00119 00120 XMLInteriorNode* _root; 00121 }; 00122 00123 00124 class XMLVisitor 00125 { 00126 public: 00127 virtual void operator()(XMLLeafNode& leaf) = 0; 00128 virtual void operator()(XMLInteriorNode& intnode) = 0; 00129 }; 00130 00131 00132 class XMLDocumentWriter : public XMLVisitor 00133 { 00134 private: 00135 QXmlStreamWriter _stream; 00136 QFile _file; 00137 bool _error; 00138 00139 void writeText(XMLLeafNode& node) 00140 { 00141 XMLLeafTag* leaftag = static_cast<XMLLeafTag*>(node._tag); 00142 for(QVector<QString>::iterator it = leaftag->_text.begin();it != leaftag->_text.end();++it) 00143 { 00144 QString tmp = ""; 00145 if (it != leaftag->_text.begin()) 00146 tmp = QString(" "); 00147 _stream.writeCharacters(tmp + *it); 00148 } 00149 } 00150 00151 void writeAttributes(XMLNode& node) 00152 { 00153 QXmlStreamAttributes attr; 00154 for(XMLTag::TagAttributes::iterator it = node._tag->_attributes.begin();it != node._tag->_attributes.end();++it) 00155 attr.append(it->first,it->second); 00156 _stream.writeAttributes(attr); 00157 } 00158 00159 void recursiveStep(XMLInteriorNode& intnode) 00160 { 00161 QVector< XMLNode* > sons = intnode.sons(); 00162 for(QVector< XMLNode* >::iterator its = sons.begin();its != sons.end();++its) 00163 (*its)->applyProcedure(*this); 00164 } 00165 00166 public: 00167 00168 void operator()(XMLLeafNode& node) 00169 { 00170 _stream.writeStartElement(node._tag->_tagname); 00171 writeAttributes(node); 00172 writeText(node); 00173 _stream.writeEndElement(); 00174 } 00175 00176 void operator()(XMLInteriorNode& intnode) 00177 { 00178 _stream.writeStartElement(intnode._tag->_tagname); 00179 writeAttributes(intnode); 00180 recursiveStep(intnode); 00181 _stream.writeEndElement(); 00182 } 00183 00184 void operator()(XMLDocument& doc) 00185 { 00186 _stream.writeStartDocument(); 00187 operator()(*(doc._root)); 00188 _stream.writeEndDocument(); 00189 } 00190 00191 void write(XMLDocument& doc) 00192 { 00193 (*this)(doc); 00194 } 00195 00196 bool isReliable() const 00197 { 00198 return !_error; 00199 } 00200 00201 XMLDocumentWriter(const char* filename,const bool autoformatting = true) 00202 :_stream(),_file(filename),_error(false) 00203 { 00204 if (!_file.open(QIODevice::WriteOnly | QIODevice::Text)) 00205 _error = true; 00206 _stream.setDevice(&_file); 00207 _stream.setAutoFormatting(autoformatting); 00208 } 00209 00210 virtual ~XMLDocumentWriter() 00211 { 00212 _file.close(); 00213 } 00214 }; 00215 00216 #endif