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 setName(std::string const &name) {
00110 Name = name;
00111 }
00112 std::string getName() 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
00129 protected:
00130 void parse(token_iterator &first, token_iterator const &last);
00131 void write(std::ostream &ostr, TSize indent);
00132
00133 void setLastText(std::string const &text) {
00134 Text.back() = text;
00135 }
00136
00137 friend class xml_file;
00138 };
00139
00140 friend class tag;
00141
00142 protected:
00143 tag *RootTag;
00144
00145 public:
00146 xml_file()
00147 : RootTag(NULL) {
00148 }
00149 ~xml_file() {
00150 if (RootTag) delete RootTag;
00151 }
00152
00153 void read(std::istream &istr);
00154 void write(std::ostream &ostr);
00155
00156 tag *getRootTag() {
00157 return RootTag;
00158 }
00159 void setRootTag(tag *newroot) {
00160 if (RootTag) delete RootTag;
00161 RootTag = newroot;
00162 }
00163 void clear() {
00164 setRootTag(NULL);
00165 }
00166
00167 protected:
00168 void parse(scanner::token_list const &tokenlist);
00169
00170 static void skipComment(token_iterator &first,token_iterator const &last);
00171 };
00172 }
00173
00174
00175
00176 #endif