Go to the documentation of this file.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.Text;
00042 using System.Xml;
00043 using System.Collections.Generic;
00044
00045 namespace XMLStorage
00046 {
00047
00048
00049
00050
00051 public class XMLStreamReader : IDisposable
00052 {
00053 private TextReader _istream;
00054 protected XmlReader _reader;
00055
00056 protected XMLStreamNode _node;
00057
00058 protected string _content = "";
00059 protected StringBuilder _instructions = new StringBuilder();
00060
00061 int _level = 0;
00062
00063 public XMLStreamReader(string path, XmlReaderSettings settings=null)
00064 {
00065 _istream = new StreamReader(path);
00066
00067 init(_istream, settings);
00068 }
00069
00070 public XMLStreamReader(StreamReader source, XmlReaderSettings settings=null)
00071 {
00072 init(source, settings);
00073 }
00074
00075 private void init(TextReader source, XmlReaderSettings settings=null)
00076 {
00077 _node = new XMLStreamNode();
00078
00079 _reader = XmlReader.Create(source, settings);
00080 }
00081
00082 public void Dispose()
00083 {
00084 _reader.Close();
00085 _reader = null;
00086
00087 if (_istream != null) {
00088 _istream.Dispose();
00089 _istream = null;
00090 }
00091 }
00092
00093
00094 public XMLStreamNode getNode()
00095 {
00096 return _node;
00097 }
00098
00099 public Object getNodeName()
00100 {
00101 return _node.getName();
00102 }
00103
00104 public bool isAtNode(string nodeName)
00105 {
00106 return _node.getName() == nodeName;
00107 }
00108
00109
00110
00111
00112
00113 public IEnumerable<XMLStreamNode> iterator()
00114 {
00115 if (firstChild())
00116 yield return _node;
00117
00118 while(next())
00119 yield return _node;
00120 }
00121
00122
00123
00124
00125
00126 public IEnumerable<XMLStreamNode> filterChildren(XMLStreamReader reader, string name)
00127 {
00128 foreach(XMLStreamNode node in iterator())
00129 {
00130 if (node.getName() == name)
00131 yield return node;
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140
00141 public string get(string attrName)
00142 {
00143 return _node.get(attrName);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 public string get(string attrName, string def)
00153 {
00154 return _node.get(attrName, def);
00155 }
00156
00157
00158
00159
00160
00161 public bool goDown()
00162 {
00163 return firstChild(null);
00164 }
00165
00166
00167
00168
00169
00170
00171 public bool goDown(string name)
00172 {
00173 return firstChild(name);
00174 }
00175
00176
00177 public bool go(XPath xpath)
00178 {
00179
00180 if (xpath._absolute)
00181 return false;
00182
00183 return findRelative(xpath);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192 public bool back()
00193 {
00194 return findNode(null, -1, _level+1, false);
00195 }
00196
00197
00198
00199
00200 public string getContent()
00201 {
00202 return _node.getContent();
00203 }
00204
00205 public override string ToString()
00206 {
00207 return _node.ToString();
00208 }
00209
00210
00211 private void startElement(string nodeName)
00212 {
00213 _node.assign(nodeName);
00214 _node.setAttributes(_reader);
00215
00216 _content = "";
00217
00218 ++_level;
00219 }
00220
00221 private void endElement(string nodeName)
00222 {
00223 _node.assign(nodeName);
00224
00225 _content = "";
00226
00227 --_level;
00228 }
00229
00230 private void characters(string str)
00231 {
00232 _content += XMLHelper.encodeXMLString(str);
00233 }
00234
00235 private void processingInstruction(string target, string data)
00236 {
00237 _instructions.Append("<?").Append(target).Append(" ").Append(data).Append("?>");
00238 }
00239
00240 public string getInstructions()
00241 {
00242 return _instructions.ToString();
00243 }
00244
00245
00246
00247
00248
00249
00250 public bool firstChild()
00251 {
00252 return findNode(null, _level+1, _level, false);
00253 }
00254
00255
00256
00257
00258
00259 public bool firstChild(string nodeName)
00260 {
00261 return findNode(nodeName, _level+1, _level, false);
00262 }
00263
00264
00265
00266
00267
00268
00269 public bool next()
00270 {
00271 return findNode(null, _level, _level-1, false);
00272 }
00273
00274
00275
00276
00277
00278 public bool nextSkipOthers(string nodeName)
00279 {
00280 return findNode(nodeName, _level, _level-1, false);
00281 }
00282
00283
00284
00285
00286
00287 public bool nextStopOnOthers(string nodeName)
00288 {
00289 return findNode(nodeName, _level, _level-1, true);
00290 }
00291
00292
00293 private bool _pendingEndElement = false;
00294
00295 private bool findNode(string targetTag, int targetLevel, int minLevel, bool stopOnOthers)
00296 {
00297 bool found = false;
00298
00299 if (!handlePendingEndElement(minLevel))
00300 return false;
00301
00302 do {
00303 switch(_reader.NodeType) {
00304 case XmlNodeType.Element: {
00305
00306 if (found)
00307 goto break_parsingLoop;
00308
00309
00310 int level = _pendingEndElement? _level-1: _level;
00311
00312 if (level+1 == targetLevel) {
00313 if (targetTag==null || _reader.Name==targetTag)
00314 found = true;
00315 else if (stopOnOthers)
00316 return false;
00317 }
00318
00319 if (_reader.IsEmptyElement) {
00320 if (!handlePendingEndElement(minLevel))
00321 return false;
00322
00323 _pendingEndElement = true;
00324 }
00325
00326 startElement(_reader.Name);
00327 break;}
00328
00329 case XmlNodeType.EndElement: {
00330
00331 if (found)
00332 goto break_parsingLoop;
00333
00334
00335 int level = _pendingEndElement? _level-1: _level;
00336 if (level == minLevel)
00337 return false;
00338
00339 endElement(_reader.Name);
00340
00341
00342 if (_level < minLevel) {
00343 _reader.Read();
00344 return false;
00345 }
00346 break;}
00347
00348 case XmlNodeType.Text:
00349
00350 characters(_reader.Value);
00351 break;
00352
00353 case XmlNodeType.CDATA:
00354
00355 characters(_reader.Value);
00356 break;
00357
00358 case XmlNodeType.Comment:
00359
00360 characters(_reader.Value);
00361 break;
00362
00363 case XmlNodeType.XmlDeclaration:
00364
00365 break;
00366
00367 case XmlNodeType.ProcessingInstruction:
00368
00369 processingInstruction(_reader.Name, _reader.Value);
00370 break;
00371
00372 case XmlNodeType.DocumentType:
00373
00374 break;
00375
00376
00377
00378
00379
00380
00381
00382 }
00383 } while(_reader.Read());
00384 break_parsingLoop:
00385
00386 if (found) {
00387 _node.setContent(_content);
00388 _content = "";
00389 return true;
00390 } else
00391 return false;
00392 }
00393
00394 private bool handlePendingEndElement(int minLevel)
00395 {
00396 if (_pendingEndElement) {
00397 _pendingEndElement = false;
00398
00399 bool withAttributes = _node.hasAttributes();
00400
00401 endElement(_node.getName());
00402
00403
00404 if (_level < minLevel) {
00405
00406
00407 if (!withAttributes)
00408 _reader.Read();
00409
00410 return false;
00411 }
00412 }
00413
00414 return true;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 public bool find(string nodeName)
00424 {
00425 return firstChild(nodeName);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 public bool find(string nodeName, int n)
00435 {
00436 if (!firstChild(nodeName))
00437 return false;
00438
00439 for(int i=1; i<n; ++i)
00440 if (!nextSkipOthers(nodeName))
00441 return false;
00442
00443 return true;
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453 public bool find(string nodeName, string attrName, string attrValue)
00454 {
00455 if (firstChild(nodeName)) {
00456 if (_node.getName()==nodeName && _node.get(attrName)==attrValue)
00457 return true;
00458
00459 while(nextSkipOthers(nodeName))
00460 if (_node.getName()==nodeName && _node.get(attrName)==attrValue)
00461 return true;
00462 }
00463
00464 return false;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 public bool find(string nodeName, string attrName, string attrValue, int n)
00476 {
00477 if (firstChild(nodeName)) {
00478 if (_node.getName()==nodeName && _node.get(attrName)==attrValue)
00479 if (n-- == 0)
00480 return true;
00481
00482 while(nextSkipOthers(nodeName))
00483 if (_node.getName()==nodeName && _node.get(attrName)==attrValue)
00484 if (n-- == 0)
00485 return true;
00486 }
00487
00488 return false;
00489 }
00490
00491
00492
00493
00494
00495
00496 bool findRelative(XPath xpath)
00497 {
00498 foreach(XPathElement xelem in xpath) {
00499 if (!find(xelem))
00500 return false;
00501 }
00502
00503 return true;
00504 }
00505
00506
00507
00508
00509
00510
00511 bool find(XPathElement xelem)
00512 {
00513 int[] n = new int[] {0};
00514
00515 if (firstChild(xelem._childName)) {
00516 if (xelem.matches(_node, n))
00517 return true;
00518
00519 while(nextSkipOthers(xelem._childName))
00520 if (xelem.matches(_node, n))
00521 return true;
00522 }
00523
00524 return false;
00525 }
00526 }
00527
00528 }