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 using System;
00040 using System.IO;
00041 using System.Collections.Generic;
00042
00043 namespace XMLStorage {
00044
00045
00046
00047
00048
00049 public class XMLNode : AbstractXMLNode
00050 {
00051 public XMLNode(string name)
00052 {
00053 _name = name;
00054 }
00055
00056 public XMLNode(string name, string leading)
00057 {
00058 _name = name;
00059 _leading = leading;
00060 }
00061
00062 public XMLNode(XMLNode other)
00063 {
00064 assign(other);
00065 }
00066
00067 protected string _name;
00068
00069 public override string getName()
00070 {
00071 return _name;
00072 }
00073
00074 public override string ToString()
00075 {
00076 return _name;
00077 }
00078
00079
00080
00081
00082 public class Children : LinkedList<XMLNode>
00083 {
00084 public void assign(Children other)
00085 {
00086 this.Clear();
00087
00088 foreach(XMLNode node in other)
00089 AddLast(new XMLNode(node));
00090 }
00091
00092 public void clear()
00093 {
00094 while(Count > 0) {
00095 XMLNode node = Last.Value;
00096 RemoveLast();
00097
00098 node.clear();
00099 }
00100 }
00101 }
00102
00103 protected Children _children = new Children();
00104
00105 public string _leading = "";
00106 public string _endLeading = "";
00107 public string _trailing = "";
00108
00109 public void clear()
00110 {
00111 _leading = "";
00112 _content = "";
00113 _endLeading = "";
00114 _trailing = "";
00115
00116 _attributes.Clear();
00117 _children.Clear();
00118
00119 _name = "";
00120 }
00121
00122 public void assign(XMLNode other)
00123 {
00124 _children.assign(other._children);
00125
00126 _attributes = (Dictionary<string, string>) other._attributes;
00127
00128 _leading = other._leading;
00129 _content = other._content;
00130 _endLeading = other._endLeading;
00131 _trailing = other._trailing;
00132 }
00133
00134
00135 public void addChild(XMLNode child)
00136 {
00137 _children.AddLast(child);
00138 }
00139
00140
00141 public override string get(string attrName)
00142 {
00143 string found;
00144
00145 if (_attributes.TryGetValue(attrName, out found))
00146 return found;
00147 else
00148 return "";
00149 }
00150
00151
00152 public override string get(string attrName, string def)
00153 {
00154 string found;
00155
00156 if (_attributes.TryGetValue(attrName, out found))
00157 return found;
00158 else
00159 return def;
00160 }
00161
00162
00163 public void put(string attrName, string value)
00164 {
00165 try {
00166 _attributes.Add(attrName, value);
00167 } catch(ArgumentException) {
00168 _attributes.Remove(attrName);
00169 _attributes.Add(attrName, value);
00170 }
00171 }
00172
00173
00174 public string getSubattrib(string nodeName, string attrName)
00175 {
00176 AbstractXMLNode node = find(nodeName);
00177
00178 if (node != null)
00179 return node.get(attrName);
00180 else
00181 return "";
00182 }
00183
00184 public string getSubattrib(string nodeName, string attrName, int n)
00185 {
00186 AbstractXMLNode node = find(nodeName, n);
00187
00188 if (node != null)
00189 return node.get(attrName);
00190 else
00191 return "";
00192 }
00193
00194
00195 public void putSubattrib(string nodeName, string attrName, string value)
00196 {
00197 XMLNode node = find(nodeName);
00198
00199 if (node == null) {
00200 node = new XMLNode(nodeName);
00201 addChild(node);
00202 }
00203
00204 node.put(attrName, value);
00205 }
00206
00207 public void putSubattrib(string nodeName, string attrName, string value, int n)
00208 {
00209 XMLNode node = find(nodeName, n);
00210
00211 if (node == null) {
00212 node = new XMLNode(nodeName);
00213 addChild(node);
00214 }
00215
00216 node.put(attrName, value);
00217 }
00218
00219 public Children getChildren()
00220 {
00221 return _children;
00222 }
00223
00224 public override string getContent()
00225 {
00226 return XMLHelper.decodeXMLString(_content);
00227 }
00228
00229 public void setContent(string s)
00230 {
00231 setContent(s, false);
00232 }
00233
00234 public void setContent(string s, bool cdata)
00235 {
00236 _content = XMLHelper.encodeXMLString(s, cdata);
00237 }
00238
00239 public enum WRITE_MODE {
00240
00241 FORMAT_SMART,
00242 FORMAT_ORIGINAL,
00243 FORMAT_PRETTY
00244 };
00245
00246 public virtual void write(TextWriter w)
00247 {
00248 write(w, WRITE_MODE.FORMAT_SMART, 0);
00249 }
00250
00251 public virtual void write(TextWriter w, WRITE_MODE mode)
00252 {
00253 write(w, mode, 0);
00254 }
00255
00256
00257 public void write(TextWriter w, WRITE_MODE mode, int indent)
00258 {
00259 switch(mode) {
00260 case WRITE_MODE.FORMAT_PRETTY:
00261 prettyWriteWorker(w, indent);
00262 break;
00263
00264 case WRITE_MODE.FORMAT_ORIGINAL:
00265 writeWorker(w, indent);
00266 break;
00267
00268 default:
00269 smartWriteWorker(w, indent);
00270 break;
00271 }
00272 }
00273
00274 public XMLNode getFirstChild()
00275 {
00276 if (_children.Count > 0)
00277 return _children.First.Value;
00278 else
00279 return null;
00280 }
00281
00282
00283
00284
00285
00286
00287 public XMLNode find(string nodeName)
00288 {
00289 foreach(XMLNode child in _children)
00290 if (child._name == nodeName)
00291 return child;
00292
00293 return null;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 public XMLNode find(string nodeName, int n)
00303 {
00304 foreach(XMLNode child in _children)
00305 if (child._name == nodeName)
00306 if (n-- == 0)
00307 return child;
00308
00309 return null;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319 public XMLNode find(string nodeName, string attrName, string attrValue)
00320 {
00321 foreach(XMLNode child in _children)
00322 if (child._name==nodeName && child.get(attrName)==attrValue)
00323 return child;
00324
00325 return null;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 public XMLNode find(string nodeName, string attrName, string attrValue, int n)
00337 {
00338 foreach(XMLNode node in _children)
00339 if (node._name==nodeName && node.get(attrName)==attrValue)
00340 if (n-- == 0)
00341 return node;
00342
00343 return null;
00344 }
00345
00346
00347 public XMLNode findRelative(XPath xpath)
00348 {
00349 XMLNode node = this;
00350
00351 foreach(XPathElement xelem in xpath)
00352 {
00353 node = xelem.find(node);
00354
00355 if (node == null)
00356 break;
00357 }
00358
00359 return node;
00360 }
00361
00362
00363 public AbstractXMLNode createRelative(XPath xpath)
00364 {
00365 XMLNode node = this;
00366
00367 foreach(XPathElement elem in xpath) {
00368 XMLNode child = elem.find(node);
00369
00370 if (child == null) {
00371 child = new XMLNode(elem._childName);
00372 node.addChild(child);
00373
00374 foreach(KeyValuePair<string, string> it in elem._mAttrAndAttr)
00375 put(it.Key, it.Value);
00376 }
00377
00378 node = child;
00379 }
00380
00381 return node;
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 protected void writeWorker(TextWriter w, int indent)
00391 {
00392 w.Write(_leading);
00393 w.Write('<');
00394 w.Write(XMLHelper.encodeXMLString(_name));
00395
00396 foreach(KeyValuePair<string,string> it in _attributes) {
00397 string attrValue = it.Value;
00398
00399 if (attrValue != null) {
00400 w.Write(' ');
00401 w.Write(XMLHelper.encodeXMLString(it.Key));
00402 w.Write("=\"");
00403 w.Write(XMLHelper.encodeXMLString(attrValue));
00404 w.Write("\"");
00405 }
00406 }
00407
00408
00409 if (_children.Count>0 || _content.Length>0) {
00410 w.Write('>');
00411 w.Write(_content);
00412
00413 foreach(XMLNode child in _children)
00414 child.writeWorker(w, indent+1);
00415
00416 w.Write(_endLeading);
00417 w.Write("</");
00418 w.Write(XMLHelper.encodeXMLString(_name));
00419 w.Write('>');
00420 } else
00421 w.Write("/>");
00422
00423 w.Write(_trailing);
00424 }
00425
00426 public static string XML_INDENT_SPACE = " ";
00427
00428 protected void prettyWriteWorker(TextWriter w, int indent)
00429 {
00430 for(int i=indent; i-->0; )
00431 w.Write(XML_INDENT_SPACE);
00432
00433 w.Write('<');
00434 w.Write(XMLHelper.encodeXMLString(_name));
00435
00436 foreach(KeyValuePair<string,string> it in _attributes) {
00437 string attrValue = it.Value;
00438
00439 if (attrValue != null) {
00440 w.Write(' ');
00441 w.Write(XMLHelper.encodeXMLString(it.Key));
00442 w.Write("=\"");
00443 w.Write(XMLHelper.encodeXMLString(attrValue));
00444 w.Write("\"");
00445 }
00446 }
00447
00448 if (_children.Count>0 || _content.Length>0) {
00449 w.Write(">\n");
00450
00451 foreach(XMLNode child in _children)
00452 child.prettyWriteWorker(w, indent+1);
00453
00454 for(int i=indent; i-->0; )
00455 w.Write(XML_INDENT_SPACE);
00456
00457 w.Write("</");
00458 w.Write(XMLHelper.encodeXMLString(_name));
00459 w.Write(">\n");
00460 } else
00461 w.Write("/>\n");
00462 }
00463
00464 protected void smartWriteWorker(TextWriter w, int indent)
00465 {
00466 if (_leading.Length == 0)
00467 for(int i=indent; i-->0; )
00468 w.Write(XML_INDENT_SPACE);
00469 else
00470 w.Write(_leading);
00471
00472 w.Write('<');
00473 w.Write(XMLHelper.encodeXMLString(_name));
00474
00475 foreach(KeyValuePair<string,string> it in _attributes) {
00476 string attrValue = it.Value;
00477
00478 if (attrValue != null) {
00479 w.Write(' ');
00480 w.Write(XMLHelper.encodeXMLString(it.Key));
00481 w.Write("=\"");
00482 w.Write(XMLHelper.encodeXMLString(attrValue));
00483 w.Write("\"");
00484 }
00485 }
00486
00487 if (_children.Count==0 && _content.Length==0)
00488 w.Write("/>");
00489 else {
00490 w.Write('>');
00491
00492 if (_content.Length == 0)
00493 w.Write('\n');
00494 else
00495 w.Write(_content);
00496
00497 LinkedListNode<XMLNode> it = _children.First;
00498
00499 if (it != null) {
00500 for( ; it != null; it = it.Next )
00501 it.Value.smartWriteWorker( w, indent + 1 );
00502
00503 if (_endLeading.Length == 0)
00504 for(int i=indent; i-->0; )
00505 w.Write(XML_INDENT_SPACE);
00506 else
00507 w.Write(_endLeading);
00508 } else
00509 w.Write(_endLeading);
00510
00511 w.Write("</");
00512 w.Write(XMLHelper.encodeXMLString(_name));
00513 w.Write('>');
00514 }
00515
00516 if (_trailing.Length == 0)
00517 w.Write('\n');
00518 else
00519 w.Write(_trailing);
00520 }
00521 }
00522
00523 }