LibXmlDomDocumentHandler.hxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 #ifndef _LibXmlDomDocumentHandler_hxx_
00022 #define _LibXmlDomDocumentHandler_hxx_
00023 
00024 #include "LibXmlDomReadingContext.hxx"
00025 #include "LibXmlDomWritingContext.hxx"
00026 #include "LibXmlDomReader.hxx"
00027 #include "LibXmlDomWriter.hxx"
00028 
00029 
00030 #include <libxml++/libxml++.h>
00031 
00032 namespace CLAM 
00033 {
00034 class LibXmlDomReadingContext;
00035 class LibXmlDomWritingContext;
00040 class LibXmlDomDocumentHandler
00041 {
00042 public:
00043         typedef LibXmlDomWritingContext WritingContext;
00044         typedef LibXmlDomReadingContext ReadingContext;
00045         ReadingContext * GetReadingContext()
00046         {
00047                 return _currentReadContext;
00048         }
00049         void SetReadingContext(ReadingContext * context)
00050         {
00051                 _currentReadContext = context;
00052         }
00053         WritingContext * GetWritingContext()
00054         {
00055                 return _currentWriteContext;
00056         }
00057         void SetWritingContext(WritingContext * context)
00058         {
00059                 _currentWriteContext = context;
00060         }
00061 private:
00062         ReadingContext * _currentReadContext;
00063         WritingContext * _currentWriteContext;
00064         xmlpp::Document * _document;
00065         xmlpp::Element * _selection;
00066         xmlpp::DomParser * _parser;
00067 public:
00068         LibXmlDomDocumentHandler()
00069         {
00070                 _document = 0;
00071                 _selection = 0;
00072                 _parser = 0;
00073         }
00074         ~LibXmlDomDocumentHandler()
00075         {
00076                 releaseIfAnyDocument();
00077         }
00078         void setDocument(xmlpp::Document * document)
00079         {
00080                 _document = document;
00081                 _selection = _document->get_root_node();
00082         }
00083         void selectPath(const char * path)
00084         {
00085                 if (path[0]!='/') 
00086                         _selection = recursiveSelection(_selection, path, 0);
00087                 else
00088                         _selection = absoluteSelection(path);
00089                 return;
00090         }
00091         xmlpp::Element * getSelection()
00092         {
00093                 return _selection;
00094         }
00095         void create(const char * rootName)
00096         {
00097                 releaseIfAnyDocument();
00098                 
00099                 xmlpp::Document * domDoc = new xmlpp::Document;
00100                 domDoc->create_root_node(rootName);
00101                 setDocument(domDoc);
00102         }
00103         void read(std::istream & stream)
00104         {
00105                 LibXmlDomReader reader;
00106                 xmlpp::Document * domDoc;
00107                 domDoc = reader.read(stream);
00108                 setDocument(domDoc);
00109                 _parser = reader.adoptParser();
00110         }
00111         void writeDocument(std::ostream & os, bool useIndentation=false)
00112         {
00113                 LibXmlDomWriter writer;
00114                 writer.DoIndentedFormat(useIndentation);
00115                 writer.write(os,_document);
00116         }
00117         void writeSelection(std::ostream & os, bool useIndentation=false)
00118         {
00119                 LibXmlDomWriter writer;
00120                 writer.DoIndentedFormat(useIndentation);
00121                 writer.write(os,_selection);
00122         }
00123 private:
00124         void releaseIfAnyDocument()
00125         {
00126                 if (!_document) return;
00127 
00128                 if (_parser)
00129                         delete _parser;
00130                 else
00131                         delete _document;
00132                 _parser=0;
00133                 _document=0;
00134         }
00135         xmlpp::Element * absoluteSelection(const std::string & path)
00136         {
00137                 xmlpp::Element * root = _document->get_root_node();
00138                 unsigned int nextSlash = std::string(path).find('/',1);
00139                 std::string rootStep = std::string(path).substr(1,nextSlash-1);
00140                 std::string rootName = root->get_name();
00141                 if (rootStep=="") return root;
00142 
00143                 if (rootName== rootStep)
00144                         return recursiveSelection(root, path, nextSlash+1);
00145 
00146                 throw XmlStorageErr("Wrong root name, expected '"+rootStep+"' but found '"+rootName+"'");
00147         }
00148         xmlpp::Element * recursiveSelection(xmlpp::Element * current, const std::string & path, unsigned int pos)
00149         {
00150                 if (pos >= path.length()) return current;
00151                 unsigned int slashPosition = path.find('/', pos);
00152                 unsigned int stepSize = 
00153                         slashPosition == std::string::npos ? 
00154                                 std::string::npos : slashPosition-pos;
00155                 std::string step = path.substr(pos, stepSize);
00156                 xmlpp::Element::NodeList children = current->get_children();
00157                 for (
00158                         xmlpp::Element::NodeList::iterator child = children.begin();
00159                         child!=children.end();
00160                         child++)
00161                 {
00162                         xmlpp::Element * element = dynamic_cast<xmlpp::Element*>(*child);
00163                         if (!element) continue;
00164                         std::string nodeName= element->get_name();
00165                         if (nodeName != step) continue;
00166                         if (slashPosition==std::string::npos) return element;
00167                         return recursiveSelection(element, path, slashPosition+1);
00168                 }
00169                 std::string msg = "Wrong path step '" + step + "'";
00170                 throw XmlStorageErr(msg);
00171         }
00172 };
00173 
00174 
00175 }
00176 
00181 #endif//_LibXmlDomDocumentHandler_hxx_
00182 
Generated by  doxygen 1.6.3