XercesDomDocumentHandler.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 _XercesDomDocumentHandler_hxx_
00022 #define _XercesDomDocumentHandler_hxx_
00023
00024 #include "XercesEncodings.hxx"
00025 #include "XercesDomReadingContext.hxx"
00026 #include "XercesDomWritingContext.hxx"
00027 #include "XercesDomReader.hxx"
00028 #include "XercesDomWriter.hxx"
00029 #include "XercesInitializer.hxx"
00030
00031
00032 #include <xercesc/parsers/XercesDOMParser.hpp>
00033 #include <xercesc/dom/DOMImplementation.hpp>
00034 #include <xercesc/dom/DOMDocument.hpp>
00035 #include <xercesc/dom/DOMElement.hpp>
00036
00037 namespace CLAM
00038 {
00039 class XercesDomReadingContext;
00040 class XercesDomWritingContext;
00041
00046 class XercesDomDocumentHandler
00047 {
00048 public:
00049 typedef XercesDomWritingContext WritingContext;
00050 typedef XercesDomReadingContext ReadingContext;
00051 ReadingContext * GetReadingContext()
00052 {
00053 return _currentReadContext;
00054 }
00055 void SetReadingContext(ReadingContext * context)
00056 {
00057 _currentReadContext = context;
00058 }
00059 WritingContext * GetWritingContext()
00060 {
00061 return _currentWriteContext;
00062 }
00063 void SetWritingContext(WritingContext * context)
00064 {
00065 _currentWriteContext = context;
00066 }
00067 private:
00068 ReadingContext * _currentReadContext;
00069 WritingContext * _currentWriteContext;
00070 xercesc::DOMDocument * _document;
00071 xercesc::DOMElement * _selection;
00072 xercesc::XercesDOMParser * _parser;
00073 public:
00074 XercesDomDocumentHandler()
00075 {
00076 _document = 0;
00077 _selection = 0;
00078 _parser = 0;
00079 }
00080 ~XercesDomDocumentHandler()
00081 {
00082 releaseIfAnyDocument();
00083 }
00084 void setDocument(xercesc::DOMDocument * document)
00085 {
00086 _document = document;
00087 _selection = _document->getDocumentElement();
00088 }
00089 void selectPath(const char * path)
00090 {
00091 if (path[0]!='/')
00092 _selection = recursiveSelection(_selection, path, 0);
00093 else
00094 _selection = absoluteSelection(path);
00095 return;
00096 }
00097
00098 xercesc::DOMElement * getSelection()
00099 {
00100 return _selection;
00101 }
00102 void create(const char * rootName)
00103 {
00104 XercesInitializer::require();
00105 releaseIfAnyDocument();
00106 xercesc::DOMImplementation * imp =
00107 xercesc::DOMImplementation::getImplementation();
00108 xercesc::DOMDocument * domDoc = imp->createDocument(0,U(rootName),0);
00109 setDocument(domDoc);
00110 }
00111 void read(std::istream & stream)
00112 {
00113 XercesDomReader reader;
00114 xercesc::DOMDocument * domDoc;
00115 domDoc = reader.read(stream);
00116 setDocument(domDoc);
00117 _parser = reader.adoptParser();
00118 }
00119 void writeDocument(std::ostream & os, bool useIndentation=false)
00120 {
00121 XercesDomWriter writer;
00122 writer.DoIndentedFormat(useIndentation);
00123 writer.write(os,_document);
00124 }
00125 void writeSelection(std::ostream & os, bool useIndentation=false)
00126 {
00127 XercesDomWriter writer;
00128 writer.DoIndentedFormat(useIndentation);
00129 writer.write(os,_selection);
00130 }
00131 private:
00132 void releaseIfAnyDocument()
00133 {
00134 if (!_document) return;
00135 if (_parser)
00136 delete _parser;
00137 else
00138 _document->release();
00139 _parser=0;
00140 _document=0;
00141 }
00142 xercesc::DOMElement * absoluteSelection(const std::string & path)
00143 {
00144 xercesc::DOMElement * root = (xercesc::DOMElement*) _document->getDocumentElement();
00145 unsigned int nextSlash = std::string(path).find('/',1);
00146 std::string rootStep = std::string(path).substr(1,nextSlash-1);
00147 std::string rootName = L(root->getNodeName());
00148 if (rootStep=="") return root;
00149
00150 if (rootName== rootStep)
00151 return recursiveSelection(root, path, nextSlash+1);
00152
00153 throw XmlStorageErr("Wrong root name, expected '"+rootStep+"' but found '"+rootName+"'");
00154 }
00155 xercesc::DOMElement * recursiveSelection(xercesc::DOMElement * current, const std::string & path, unsigned int pos)
00156 {
00157 if (pos >= path.length()) return current;
00158 unsigned int slashPosition = path.find('/', pos);
00159 unsigned int stepSize =
00160 slashPosition == std::string::npos ?
00161 std::string::npos : slashPosition-pos;
00162 std::string step = path.substr(pos, stepSize);
00163 for (
00164 xercesc::DOMNode * child = current->getFirstChild();
00165 child;
00166 child = child->getNextSibling())
00167 {
00168 if (child->getNodeType() != xercesc::DOMNode::ELEMENT_NODE) continue;
00169 std::string nodeName(L(child->getNodeName()));
00170 if (nodeName != step) continue;
00171 if (slashPosition==std::string::npos) return (xercesc::DOMElement *) child;
00172 return recursiveSelection((xercesc::DOMElement *) child, path, slashPosition+1);
00173 }
00174 std::string msg = "Wrong path step '" + step + "'";
00175 throw XmlStorageErr(msg);
00176 }
00177
00178 };
00179
00180
00181 }
00182
00188 #endif//_XercesDomDocumentHandler_hxx_
00189