00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include <string>
00065 using std::string;
00066
00067 template <typename T>
00068 class TreeNode
00069 {
00070 private:
00071 T *parent;
00072 T *child;
00073 T *next;
00074 T *prev;
00075 T &othis;
00076 public:
00077 TreeNode(T &a_othis)
00078 :
00079 parent(NULL), child(NULL), next(NULL), prev(NULL), othis(a_othis)
00080 {}
00081 T* addChild(T *ch)
00082 {
00083 if (ch==NULL) return ch;
00084 if (child==NULL)
00085 {
00086 child=ch;
00087 ch->parent=&othis;
00088 }
00089 else child->getLastRecur().setNext(ch);
00090 return ch;
00091 }
00092
00093 T& getLastRecur()
00094 {
00095 if (next!=NULL) return next->getLastRecur();
00096 else return othis;
00097 }
00098
00099 void setNext(T *ch)
00100 {
00101 for (T *cur=ch; cur!=NULL; cur=cur->next)
00102 {
00103 cur->parent=parent;
00104 }
00105 next=ch;
00106 next->prev=&othis;
00107 }
00108 T const *getFirstChild() const
00109 {
00110 return child;
00111 }
00112 T *getFirstChild()
00113 {
00114 return child;
00115 }
00116 T const *getNext() const
00117 {
00118 return next;
00119 }
00120 T *getNext()
00121 {
00122 return next;
00123 }
00124 };
00125
00126 class XmlNode : public TreeNode <XmlNode>
00127 {
00128 public:
00129 XmlNode()
00130 :
00131 TreeNode<XmlNode>(*this)
00132 {}
00133 virtual string getString(int indent=0) const
00134 {
00135 return "";
00136 }
00137 };
00138
00139
00140 class XmlText : public XmlNode
00141 {
00142 private:
00143 string text;
00144 public:
00145 XmlText(string const &is);
00146
00147 string getString(int indent=0) const;
00148 };
00149
00150 XmlText::XmlText(string const &a_text)
00151 :
00152 text(a_text)
00153 {
00154 }
00155 string XmlText::getString(int indent=0) const
00156 {
00157 return text;
00158 }
00159
00160 class XmlTag : public XmlNode
00161 {
00162 private:
00163 string tag;
00164
00165 public:
00166 XmlTag(string a_tag);
00167 string getString(int indent=0) const;
00168 };
00169
00170 XmlTag::XmlTag(string a_tag)
00171 :
00172 tag(a_tag)
00173 {
00174 }
00175
00176 string XmlTag::getString(int indent=0) const
00177 {
00178 string output;
00179
00180 if (indent>0)
00181 output+='\n';
00182
00183 for (int i=0; i<indent; ++i)
00184 output+=' ';
00185
00186 output+=string("<")+tag;
00187
00188 if (getFirstChild()==NULL) return output+" />";
00189 else
00190 {
00191 output+=">";
00192 for (XmlNode const *cur=getFirstChild(); cur!=NULL; cur=cur->getNext())
00193 {
00194 output+=cur->getString(indent+3);
00195 }
00196 output+=string("</")+tag+">";
00197 }
00198
00199 return output;
00200 }
00201 class XmlTree public XmlNode;
00202 {
00203 static string getString(XmlNode const &);
00204 };
00205 string XmlTree::getString(XmlNode const &top)
00206 {
00207 string output
00208 int indent=0;
00209 for (XmlNode const *cur=top; cur!=NULL)
00210 {
00211 if (cur->getFirstChild()!==NULL)
00212 {
00213 output+=
00214 }
00215 }
00216 }
00217 #include <iostream>
00218 int main()
00219 {
00220 XmlTag top("xml");
00221 top.addChild(new XmlTag("contents"))->addChild(new XmlText("Foo"));
00222 std::cout<<top.getString()<<std::endl;
00223 return 0;
00224 }