/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2008 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #ifndef _XML_DOCUMENT_MANAGING_H #define _XML_DOCUMENT_MANAGING_H #include #include #include #include #include #include #include class XMLTag { public: typedef std::pair TagAttribute; typedef QVector TagAttributes; QString _tagname; TagAttributes _attributes; XMLTag(const QString& tagname = QString(),const TagAttributes& attr = TagAttributes()) :_tagname(tagname),_attributes(attr) { } virtual ~XMLTag() { } }; class XMLLeafTag : public XMLTag { public: QVector _text; XMLLeafTag(const QString& tagname = QString(),const QVector& text = QVector()) :XMLTag(tagname),_text(text) { } virtual ~XMLLeafTag() { } }; class XMLDocumentWriter; class Visitor; class XMLNode { public: XMLNode(XMLTag* tag); virtual ~XMLNode(); virtual void applyProcedure(Visitor& v) = 0; XMLTag* _tag; }; class XMLInteriorNode : public XMLNode { public: XMLInteriorNode(XMLTag* tag); XMLNode* son(int ii); QVector< XMLNode* > sons(); void applyProcedure(Visitor& v); ~XMLInteriorNode(); QVector< XMLNode* > _sons; }; class XMLLeafNode : public XMLNode { public: XMLLeafNode(XMLLeafTag* leaftag); void applyProcedure(Visitor& v); virtual ~XMLLeafNode(); }; class XMLDocument { public: XMLDocument(XMLInteriorNode* root) :_root(root) { } ~XMLDocument() { delete (_root); } XMLInteriorNode* _root; }; class Visitor { public: virtual void operator()(XMLLeafNode& leaf) = 0; virtual void operator()(XMLInteriorNode& intnode) = 0; }; class XMLDocumentWriter : public Visitor { private: QXmlStreamWriter _stream; QFile _file; bool _error; void writeText(XMLLeafNode& node) { XMLLeafTag* leaftag = static_cast(node._tag); for(QVector::iterator it = leaftag->_text.begin();it != leaftag->_text.end();++it) { QString tmp = ""; if (it != leaftag->_text.begin()) tmp = QString(" "); _stream.writeCharacters(tmp + *it); } } void writeAttributes(XMLNode& node) { QXmlStreamAttributes attr; for(XMLTag::TagAttributes::iterator it = node._tag->_attributes.begin();it != node._tag->_attributes.end();++it) attr.append(it->first,it->second); _stream.writeAttributes(attr); } void recursiveStep(XMLInteriorNode& intnode) { QVector< XMLNode* > sons = intnode.sons(); for(QVector< XMLNode* >::iterator its = sons.begin();its != sons.end();++its) (*its)->applyProcedure(*this); } public: void operator()(XMLLeafNode& node) { _stream.writeStartElement(node._tag->_tagname); writeAttributes(node); writeText(node); _stream.writeEndElement(); } void operator()(XMLInteriorNode& intnode) { _stream.writeStartElement(intnode._tag->_tagname); writeAttributes(intnode); recursiveStep(intnode); _stream.writeEndElement(); } void operator()(XMLDocument& doc) { _stream.writeStartDocument(); operator()(*(doc._root)); _stream.writeEndDocument(); } void write(XMLDocument& doc) { (*this)(doc); } bool isReliable() const { return !_error; } XMLDocumentWriter(const char* filename,const bool autoformatting = true) :_stream(),_file(filename),_error(false) { if (!_file.open(QIODevice::WriteOnly | QIODevice::Text)) _error = true; _stream.setDevice(&_file); _stream.setAutoFormatting(autoformatting); } ~XMLDocumentWriter() { _file.close(); } }; #endif