00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef XML_TREE_HPP
00021 #define XML_TREE_HPP
00022
00023 #include <ReferenceCounting.hpp>
00024 #include <XMLTag.hpp>
00025
00026 #include <Assert.hpp>
00027
00028 #include <vector>
00029 #include <string>
00030 #include <map>
00031
00039 class XMLTree
00040 {
00041 public:
00042 typedef std::multimap<std::string,
00043 ReferenceCounting<XMLTag> > TagList;
00044
00045 typedef std::pair<TagList::iterator,TagList::iterator> range;
00046 typedef std::pair<TagList::const_iterator,TagList::const_iterator> const_range;
00047
00048 private:
00049 TagList __tagList;
00051 std::vector<ReferenceCounting<XMLTag> >
00052 __openTags;
00058 XMLTree(const XMLTree&);
00059
00065 std::string
00066 __getFullTagName() const
00067 {
00068 std::string path;
00069 for (std::vector<ReferenceCounting<XMLTag> >::const_iterator i=__openTags.begin();
00070 i != __openTags.end(); ++i) {
00071 path += '>'+(*i)->name();
00072 }
00073 return path;
00074 }
00075
00083 std::string
00084 __tagFromPath(const std::string& pathName) const;
00085
00086 public:
00094 void setHead(const std::string& xml,
00095 const std::string& version,
00096 const std::string& versionNumber)
00097 {
00098 if ((xml != "xml")or(version != "version")or(versionNumber != "1.0"))
00099 {
00100 throw ErrorHandler(__FILE__,__LINE__,
00101 "cannot read file format: <?"+xml+" "+version+"=\""+versionNumber+"\"?>",
00102 ErrorHandler::normal);
00103 }
00104 }
00105
00110 void check() const;
00111
00118 void checkRange(const std::string& pathName,
00119 const_range r) const;
00120
00126 void addTag(ReferenceCounting<XMLTag> tag);
00127
00133 void closeTag(const std::string& tagName);
00134
00140 TagList::const_iterator end() const
00141 {
00142 return __tagList.end();
00143 }
00144
00150 bool hasOpenTag() const
00151 {
00152 return (__openTags.rbegin() != __openTags.rend());
00153 }
00154
00160 ReferenceCounting<XMLTag>
00161 getCurrentTag()
00162 {
00163 return *__openTags.rbegin();
00164 }
00165
00171 ConstReferenceCounting<XMLTag>
00172 getCurrentTag() const
00173 {
00174 return *__openTags.rbegin();
00175 }
00176
00184 bool hasTag(const std::string& pathName) const
00185 {
00186 ASSERT(pathName[0] == '>');
00187 return (__tagList.find(pathName) != __tagList.end());
00188 }
00189
00197 ReferenceCounting<XMLTag>
00198 findTag(const std::string& pathName)
00199 {
00200 ASSERT(pathName[0] == '>');
00201 range r = __tagList.equal_range(pathName);
00202 this->checkRange(pathName,r);
00203 if (distance(r.first, r.second) != 1) {
00204 throw ErrorHandler(__FILE__,__LINE__,
00205 "tag "+this->__tagFromPath(pathName)+" is not unique!",
00206 ErrorHandler::normal);
00207 }
00208
00209 return r.first->second;
00210 }
00211
00219 ReferenceCounting<XMLTag>
00220 findTag(const std::string& pathName) const
00221 {
00222 ASSERT(pathName[0] == '>');
00223 const_range r = __tagList.equal_range(pathName);
00224 this->checkRange(pathName,r);
00225 if (distance(r.first, r.second) != 1) {
00226 throw ErrorHandler(__FILE__,__LINE__,
00227 "tag "+this->__tagFromPath(pathName)+" is not unique!",
00228 ErrorHandler::normal);
00229 }
00230 return r.first->second;
00231 }
00232
00240 range
00241 findTagRange(const std::string& pathName)
00242 {
00243 ASSERT(pathName[0] == '>');
00244 range r = __tagList.equal_range(pathName);
00245 this->checkRange(pathName,r);
00246 return r;
00247 }
00248
00256 const_range
00257 findTagRange(const std::string& pathName) const
00258 {
00259 ASSERT(pathName[0] == '>');
00260 const_range r = __tagList.equal_range(pathName);
00261 this->checkRange(pathName,r);
00262 return r;
00263 }
00264
00269 XMLTree()
00270 {
00271 ;
00272 }
00273
00278 ~XMLTree()
00279 {
00280 ;
00281 }
00282 };
00283
00284 #endif // XML_TREE_HPP