XmlDocument.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2007, 2008, 2009, 2010, 2011 Instituto de Sistemas e Robotica, Instituto Superior Tecnico
00003 
00004 This file is part of MeRMaID.
00005 
00006 MeRMaID is free software: you can redistribute it and/or modify
00007 it under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation, either version 3 of the License, or
00009 (at your option) any later version.
00010 
00011 MeRMaID 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 Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License
00017 along with MeRMaID.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 
00022 /**
00023  * @Filename XmlDocument.cpp
00024  * @Description Implementation of the XmlDocument class
00025  * @Status Finished
00026  * @Version $Id: XmlDocument.cpp 1 2011-03-04 18:13:18Z jreis $
00027  * @Maintainer Nelson Ramos (nmsra@mega.ist.utl.pt)
00028  */
00029 
00030 #include "config.h"
00031 
00032 #include "XmlDocument.hpp"
00033 
00034 #include <Exception.hpp>
00035 #include <FilePathSearch.hpp>
00036 
00037 #include "XmlElement.hpp"
00038 #include "XmlEntityLoader.hpp"
00039 
00040 using namespace mermaid::support::xml;
00041 using mermaid::support::errorhandling::Exception;
00042 using mermaid::support::system::FilePathSearch;
00043 
00044 
00045 
00046 XmlDocument::XmlDocument()
00047 {
00048   isWellFormed_ = false;
00049   isValid_ = false;
00050   rootElement_ = shared_ptr<XmlElement>();
00051 }
00052 
00053 
00054 
00055 XmlDocument::XmlDocument (const XmlDocument& xd)
00056 {
00057   copyFrom (xd);
00058 }
00059 
00060 
00061 
00062 XmlDocument * XmlDocument::clone()
00063 {
00064   return new XmlDocument (*this);
00065 }
00066 
00067 
00068 
00069 XmlDocument::~XmlDocument()
00070 {
00071   cleanUp();
00072 }
00073 
00074 
00075 
00076 XmlDocument& XmlDocument::operator= (const XmlDocument & xd)
00077 {
00078   // make sure not same object
00079   if (this != &xd) {
00080     cleanUp();
00081     copyFrom (xd);
00082   }
00083   return *this;
00084 }
00085 
00086 
00087 
00088 void XmlDocument::parseFile (string name, bool enforceDtdValidation)
00089 {
00090   // cleanup before parsing, to avoid bugs with 2 successive parses
00091   cleanUp();
00092   
00093   xmlNodePtr rootElementNode;
00094   
00095   // get the file's full path
00096   string fileFullPath = FilePathSearch::getFullPathForFile (name);
00097   
00098   xmlSetExternalEntityLoader (&XmlEntityLoader::loaderFunction);
00099   xmlParserCtxtPtr parserCtxtPtr = xmlNewParserCtxt();
00100   xmlDocPtr docPtr;
00101   if (enforceDtdValidation == true) {
00102     docPtr = xmlCtxtReadFile (parserCtxtPtr,
00103                               fileFullPath.data(),
00104                               NULL,
00105                               XML_PARSE_DTDVALID
00106                               | XML_PARSE_NOERROR
00107                               | XML_PARSE_NOWARNING);
00108   }
00109   else {
00110     docPtr = xmlCtxtReadFile (parserCtxtPtr,
00111                               name.data(),
00112                               NULL,
00113                               XML_PARSE_NOERROR
00114                               | XML_PARSE_NOWARNING);
00115   }
00116   
00117   
00118   if ( (parserCtxtPtr->wellFormed == 0) || (docPtr == NULL)) {
00119     throw Exception ("XmlDocument::parseFile : impossible to read file or "
00120                      "document is not well formed : file=" + name);
00121   }
00122   
00123   rootElementNode = xmlDocGetRootElement (docPtr);
00124   
00125   if (rootElementNode == NULL) {
00126     xmlFreeDoc (docPtr);
00127     throw Exception ("XmlDocument::parseFile : could not retrieve "
00128                      "root element");
00129   }
00130   
00131   xmlNodePtr rootNodePtr = rootElementNode; // libxml2
00132   
00133   // non-libxml2 data
00134   isWellFormed_ = (parserCtxtPtr->wellFormed != 0);
00135   isValid_ = (parserCtxtPtr->valid != 0);;
00136   
00137   if ( (enforceDtdValidation == true) && (isValid_ == false)) {
00138     // throw Exception("XmlDocument::parseFile : validation of XML file failed : file=" + name);
00139   }
00140   
00141   rootElement_ = shared_ptr<XmlElement> (new XmlElement (rootNodePtr));
00142   
00143   if (parserCtxtPtr != NULL) {
00144     xmlFreeParserCtxt (parserCtxtPtr);
00145   }
00146   
00147   if (docPtr != NULL) {
00148     xmlFreeDoc (docPtr);
00149   }
00150 }
00151 
00152 
00153 
00154 void XmlDocument::parseString (string xml)
00155 {
00156   // cleanup before parsing, to avoid bugs with 2 successive parses
00157   cleanUp();
00158   
00159   xmlNodePtr rootElementNode;
00160   
00161   xmlParserCtxtPtr parserCtxtPtr = xmlNewParserCtxt();
00162   xmlDocPtr docPtr = xmlCtxtReadMemory (parserCtxtPtr,
00163                                         xml.data(),
00164                                         xml.size(),
00165                                         NULL,
00166                                         NULL,
00167                                         0);
00168                                         
00169   if ( (parserCtxtPtr->wellFormed == 0) || (docPtr == NULL)) {
00170     throw Exception ("XmlDocument::parseString : could not read string or XML "
00171                      "is not well formed");
00172   }
00173   
00174   rootElementNode = xmlDocGetRootElement (docPtr);
00175   
00176   if (rootElementNode == NULL) {
00177     xmlFreeDoc (docPtr);
00178     throw Exception ("XmlDocument::parseString : could not retrieve root element");
00179   }
00180   
00181   xmlNodePtr rootNodePtr = rootElementNode; // libxml2
00182   
00183   // non-libxml2 data
00184   isWellFormed_ = (parserCtxtPtr->wellFormed != 0);
00185   isValid_ = (parserCtxtPtr->valid != 0);;
00186   rootElement_ = shared_ptr<XmlElement> (new XmlElement (rootNodePtr));
00187   
00188   if (parserCtxtPtr != NULL) {
00189     xmlFreeParserCtxt (parserCtxtPtr);
00190   }
00191   
00192   if (docPtr != NULL) {
00193     xmlFreeDoc (docPtr);
00194   }
00195 }
00196 
00197 
00198 
00199 shared_ptr<XmlElement> XmlDocument::getRootElement()
00200 {
00201   if (this->isWellFormed()) {
00202     return rootElement_;
00203   }
00204   else {
00205     throw Exception ("XmlDocument::getRootElement() : no root "
00206                      "element available");
00207   }
00208 }
00209 
00210 
00211 
00212 bool XmlDocument::isWellFormed()
00213 {
00214   return isWellFormed_;
00215 }
00216 
00217 
00218 
00219 bool XmlDocument::isValid()
00220 {
00221   return isValid_;
00222 }
00223 
00224 
00225 
00226 void XmlDocument::copyFrom (const XmlDocument& xd)
00227 {
00228   isWellFormed_ = xd.isWellFormed_;
00229   isValid_ = xd.isValid_;
00230   rootElement_ = xd.rootElement_;
00231 }
00232 
00233 
00234 
00235 void XmlDocument::cleanUp()
00236 {
00237   rootElement_ = shared_ptr<XmlElement>();
00238 }
Generated on Fri Mar 4 22:14:58 2011 for MeRMaID::support by  doxygen 1.6.3