00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef XML_TAG_HPP
00021 #define XML_TAG_HPP
00022
00023 #include <ReferenceCounting.hpp>
00024
00025 #include <XMLContentBase.hpp>
00026 #include <XMLAttribute.hpp>
00027
00028 #include <ErrorHandler.hpp>
00029
00030 #include <Assert.hpp>
00031
00032 #include <iostream>
00033 #include <string>
00034
00042 class XMLTag
00043 {
00044 private:
00045 typedef std::map<std::string,
00046 ReferenceCounting<XMLAttribute> > AttributeList;
00047
00048 const std::string
00049 __name;
00051 AttributeList __attributes;
00053 ReferenceCounting<XMLContentBase>
00054 __content;
00056 public:
00065 ReferenceCounting<XMLAttribute>
00066 findAttribute(const std::string& name,
00067 const std::string& defaultValue = "") const
00068 {
00069 AttributeList::const_iterator attribute = __attributes.find(name);
00070 if (attribute == __attributes.end()) {
00071 if (defaultValue.size() == 0) {
00072 throw ErrorHandler(__FILE__,__LINE__,
00073 "cannot find mandatory attribute '"+name+"' into <"+stringify(*this)+">",
00074 ErrorHandler::normal);
00075 } else {
00076 return new XMLAttribute(name,defaultValue);
00077 }
00078 }
00079
00080 return attribute->second;
00081 }
00082
00091 friend std::ostream& operator<< (std::ostream& os,
00092 const XMLTag& xmlTag)
00093 {
00094 os << xmlTag.__name;
00095 for (AttributeList::const_iterator i = xmlTag.__attributes.begin();
00096 i != xmlTag.__attributes.end(); ++i) {
00097 os << ' ' << i->second->name() << "=\""
00098 << i->second->value() << '"';
00099 }
00100 return os;
00101 }
00102
00108 void close(const std::string& name)
00109 {
00110 if (__name != name) {
00111 throw ErrorHandler(__FILE__,__LINE__,
00112 "tag <"+__name+"> closed by </"+name+">",
00113 ErrorHandler::normal);
00114 }
00115 }
00116
00122 void add(ReferenceCounting<XMLAttribute> xmlAttribute)
00123 {
00124 if (__attributes.find(xmlAttribute->name()) != __attributes.end()) {
00125 throw ErrorHandler(__FILE__,__LINE__,
00126 "duplicated attribute '"+
00127 xmlAttribute->name()+
00128 "' in tag '"+__name+'\'',
00129 ErrorHandler::normal);
00130 }
00131 __attributes[xmlAttribute->name()] = xmlAttribute;
00132 }
00133
00139 void add(ReferenceCounting<XMLContentBase> xmlContent)
00140 {
00141 ASSERT(__content == 0);
00142 __content = xmlContent;
00143 }
00144
00150 ReferenceCounting<XMLContentBase>
00151 content()
00152 {
00153 return __content;
00154 }
00155
00161 ConstReferenceCounting<XMLContentBase>
00162 content() const
00163 {
00164 return __content;
00165 }
00166
00172 const std::string&
00173 name() const
00174 {
00175 return __name;
00176 }
00177
00183 XMLTag(const std::string& name)
00184 : __name(name),
00185 __content(0)
00186 {
00187 ;
00188 }
00189 };
00190
00191 #endif // XML_TAG_HPP