LibXmlDomDocumentHandler.hxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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