00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef IXLIB_XML
00011 #define IXLIB_XML
00012
00013
00014
00015
00016 #include <vector>
00017 #include <map>
00018 #include <ixlib_exbase.hh>
00019 #include <ixlib_scanner.hh>
00020
00021
00022
00023
00024
00025 #define ECXML_SYNTAX 0
00026 #define ECXML_NOTEXTHERE 1
00027 #define ECXML_NOLITHERE 2
00028 #define ECXML_LITEXPECTED 3
00029 #define ECXML_UNEXPECTEDEND 4
00030 #define ECXML_CLOSETAGEXPECTED 5
00031 #define ECXML_CLOSETAGNAME 6
00032 #define ECXML_UNTERMCOMMENT 7
00033
00034
00035
00036
00037
00038 namespace ixion {
00039 struct xml_exception : public base_exception {
00040 xml_exception(TErrorCode error,char const *info = NULL,char *module = NULL,
00041 TIndex line = 0,char *category = NULL)
00042 : base_exception(error,info,module,line,"XML") {
00043 }
00044 xml_exception(TErrorCode error, TIndex line = 0, char const *info = 0);
00045 virtual char *getText() const;
00046 };
00047
00048
00049
00050
00051
00052 #define EXXML_THROW(CODE,TOKEN)\
00053 throw xml_exception(CODE,(TOKEN).Line,NULL);
00054
00055
00056
00057
00058
00072 class xml_file {
00073 protected:
00074 typedef scanner::token_list::const_iterator token_iterator;
00075
00076 public:
00077 class tag {
00078 protected:
00079 std::string Name;
00080
00081 public:
00082 typedef std::map<std::string,std::string> attribute_map;
00083 typedef std::vector<tag *> children_list;
00084 typedef std::vector<std::string> text_list;
00085
00086 attribute_map Attributes;
00087 children_list Children;
00088 text_list Text;
00089
00090 typedef children_list::iterator iterator;
00091 typedef children_list::const_iterator const_iterator;
00092
00093 tag() {
00094 Text.push_back("");
00095 }
00096 tag(std::string const &name)
00097 : Name(name) {
00098 Text.push_back("");
00099 }
00100 tag(tag const &source);
00101 ~tag();
00102 void appendTag(tag *tag) {
00103 insertTag(Text.end(),tag);
00104 }
00105 void insertTag(children_list::iterator before,tag *tag);
00106 void insertTag(text_list::iterator before,tag *tag);
00107 tag *findTag(std::string const &name);
00108
00109 void name(std::string const &name) {
00110 Name = name;
00111 }
00112 std::string name() const {
00113 return Name;
00114 }
00115
00116 iterator begin() {
00117 return Children.begin();
00118 }
00119 const_iterator begin() const {
00120 return Children.begin();
00121 }
00122 iterator end() {
00123 return Children.end();
00124 }
00125 const_iterator end() const {
00126 return Children.end();
00127 }
00128
00130 void setName(std::string const &n) {
00131 name(n);
00132 }
00134 std::string getName() const {
00135 return name();
00136 }
00137
00138 protected:
00139 void parse(token_iterator &first, token_iterator const &last);
00140 void write(std::ostream &ostr, TSize indent);
00141
00142 void setLastText(std::string const &text) {
00143 Text.back() = text;
00144 }
00145
00146 friend class xml_file;
00147 };
00148
00149 friend class tag;
00150
00151 protected:
00152 tag *RootTag;
00153
00154 public:
00155 xml_file()
00156 : RootTag(NULL) {
00157 }
00158 ~xml_file() {
00159 if (RootTag) delete RootTag;
00160 }
00161
00162 void read(std::istream &istr);
00163 void write(std::ostream &ostr);
00164
00165 tag *rootTag() const {
00166 return RootTag;
00167 }
00168 void rootTag(tag *newroot) {
00169 if (RootTag) delete RootTag;
00170 RootTag = newroot;
00171 }
00172 void clear() {
00173 setRootTag(NULL);
00174 }
00175
00177 tag *getRootTag() const {
00178 return rootTag();
00179 }
00181 void setRootTag(tag *newroot) {
00182 rootTag(newroot);
00183 }
00184 protected:
00185 void parse(scanner::token_list const &tokenlist);
00186
00187 static void skipComment(token_iterator &first,token_iterator const &last);
00188 };
00189 }
00190
00191
00192
00193 #endif