XmlReader.cs 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631
  1. //
  2. // XmlReader.cs
  3. //
  4. // Authors:
  5. // Jason Diamond ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. // Atsushi Enomoto ([email protected])
  8. //
  9. // (C) 2001, 2002 Jason Diamond http://injektilo.org/
  10. // (c) 2002 Ximian, Inc. (http://www.ximian.com)
  11. // (C) 2003 Atsushi Enomoto
  12. //
  13. //
  14. // Permission is hereby granted, free of charge, to any person obtaining
  15. // a copy of this software and associated documentation files (the
  16. // "Software"), to deal in the Software without restriction, including
  17. // without limitation the rights to use, copy, modify, merge, publish,
  18. // distribute, sublicense, and/or sell copies of the Software, and to
  19. // permit persons to whom the Software is furnished to do so, subject to
  20. // the following conditions:
  21. //
  22. // The above copyright notice and this permission notice shall be
  23. // included in all copies or substantial portions of the Software.
  24. //
  25. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  26. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  27. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  28. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  29. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  30. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  31. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  32. //
  33. using System.Collections;
  34. using System.Diagnostics;
  35. using System.IO;
  36. using System.Text;
  37. using System.Xml.Schema; // only required for NET_2_0 (SchemaInfo)
  38. using System.Xml.Serialization; // only required for NET_2_0 (SchemaInfo)
  39. using Mono.Xml.Schema; // only required for NET_2_0
  40. using Mono.Xml; // only required for NET_2_0
  41. #if NET_4_5
  42. using System.Threading;
  43. using System.Threading.Tasks;
  44. #endif
  45. namespace System.Xml
  46. {
  47. #if NET_2_0
  48. public abstract class XmlReader : IDisposable
  49. #else
  50. public abstract class XmlReader
  51. #endif
  52. {
  53. private StringBuilder readStringBuffer;
  54. private XmlReaderBinarySupport binary;
  55. #if NET_2_0
  56. private XmlReaderSettings settings;
  57. #endif
  58. #region Constructor
  59. protected XmlReader ()
  60. {
  61. }
  62. #endregion
  63. #region Properties
  64. public abstract int AttributeCount { get; }
  65. public abstract string BaseURI { get; }
  66. internal XmlReaderBinarySupport Binary {
  67. get { return binary; }
  68. }
  69. internal XmlReaderBinarySupport.CharGetter BinaryCharGetter {
  70. get { return binary != null ? binary.Getter : null; }
  71. set {
  72. if (binary == null)
  73. binary = new XmlReaderBinarySupport (this);
  74. binary.Getter = value;
  75. }
  76. }
  77. #if NET_2_0
  78. // To enable it internally in sys.xml, just insert these
  79. // two lines into Read():
  80. //
  81. // #if NET_2_0
  82. // if (Binary != null)
  83. // Binary.Reset ();
  84. // #endif
  85. //
  86. public virtual bool CanReadBinaryContent {
  87. get { return false; }
  88. }
  89. public virtual bool CanReadValueChunk {
  90. get { return false; }
  91. }
  92. #else
  93. internal virtual bool CanReadBinaryContent {
  94. get { return false; }
  95. }
  96. internal virtual bool CanReadValueChunk {
  97. get { return false; }
  98. }
  99. #endif
  100. public virtual bool CanResolveEntity
  101. {
  102. get { return false; }
  103. }
  104. public abstract int Depth { get; }
  105. public abstract bool EOF { get; }
  106. public virtual bool HasAttributes
  107. {
  108. get { return AttributeCount > 0; }
  109. }
  110. #if NET_4_0
  111. public virtual bool HasValue {
  112. get {
  113. switch (NodeType) {
  114. case XmlNodeType.Attribute:
  115. case XmlNodeType.Comment:
  116. case XmlNodeType.ProcessingInstruction:
  117. case XmlNodeType.SignificantWhitespace:
  118. case XmlNodeType.CDATA:
  119. case XmlNodeType.Text:
  120. case XmlNodeType.Whitespace:
  121. case XmlNodeType.XmlDeclaration:
  122. return true;
  123. }
  124. return false;
  125. }
  126. }
  127. #else
  128. public abstract bool HasValue { get; }
  129. #endif
  130. public abstract bool IsEmptyElement { get; }
  131. #if NET_2_0
  132. public virtual bool IsDefault {
  133. get { return false; }
  134. }
  135. public virtual string this [int i] {
  136. get { return GetAttribute (i); }
  137. }
  138. public virtual string this [string name] {
  139. get { return GetAttribute (name); }
  140. }
  141. public virtual string this [string name, string namespaceURI] {
  142. get { return GetAttribute (name, namespaceURI); }
  143. }
  144. #else
  145. public abstract bool IsDefault { get; }
  146. public abstract string this [int i] { get; }
  147. public abstract string this [string name] { get; }
  148. public abstract string this [string localName, string namespaceName] { get; }
  149. #endif
  150. public abstract string LocalName { get; }
  151. #if NET_2_0
  152. public virtual string Name {
  153. get {
  154. return Prefix.Length > 0 ?
  155. String.Concat (Prefix, ":", LocalName) :
  156. LocalName;
  157. }
  158. }
  159. #else
  160. public abstract string Name { get; }
  161. #endif
  162. public abstract string NamespaceURI { get; }
  163. public abstract XmlNameTable NameTable { get; }
  164. public abstract XmlNodeType NodeType { get; }
  165. public abstract string Prefix { get; }
  166. #if NET_2_0
  167. public virtual char QuoteChar {
  168. get { return '\"'; }
  169. }
  170. #else
  171. public abstract char QuoteChar { get; }
  172. #endif
  173. public abstract ReadState ReadState { get; }
  174. #if NET_2_0
  175. public virtual IXmlSchemaInfo SchemaInfo {
  176. get { return null; }
  177. }
  178. public virtual XmlReaderSettings Settings {
  179. get { return settings; }
  180. }
  181. #endif
  182. public abstract string Value { get; }
  183. #if NET_2_0
  184. public virtual string XmlLang {
  185. get { return String.Empty; }
  186. }
  187. public virtual XmlSpace XmlSpace {
  188. get { return XmlSpace.None; }
  189. }
  190. #else
  191. public abstract string XmlLang { get; }
  192. public abstract XmlSpace XmlSpace { get; }
  193. #endif
  194. #endregion
  195. #region Methods
  196. #if NET_4_5
  197. public virtual void Close ()
  198. {
  199. if (asyncRunning)
  200. throw new InvalidOperationException ("An asynchronous operation is already in progress.");
  201. }
  202. #else
  203. public abstract void Close ();
  204. #endif
  205. #if NET_2_0
  206. private static XmlNameTable PopulateNameTable (
  207. XmlReaderSettings settings)
  208. {
  209. XmlNameTable nameTable = settings.NameTable;
  210. if (nameTable == null)
  211. nameTable = new NameTable ();
  212. return nameTable;
  213. }
  214. private static XmlParserContext PopulateParserContext (
  215. XmlReaderSettings settings, string baseUri)
  216. {
  217. XmlNameTable nt = PopulateNameTable (settings);
  218. return new XmlParserContext (nt,
  219. new XmlNamespaceManager (nt),
  220. null,
  221. null,
  222. null,
  223. null,
  224. baseUri,
  225. null,
  226. XmlSpace.None,
  227. null);
  228. }
  229. private static XmlNodeType GetNodeType (
  230. XmlReaderSettings settings)
  231. {
  232. ConformanceLevel level = settings != null ? settings.ConformanceLevel : ConformanceLevel.Auto;
  233. return
  234. level == ConformanceLevel.Fragment ?
  235. XmlNodeType.Element :
  236. XmlNodeType.Document;
  237. }
  238. public static XmlReader Create (Stream input)
  239. {
  240. return Create (input, null);
  241. }
  242. public static XmlReader Create (string inputUri)
  243. {
  244. return Create (inputUri, null);
  245. }
  246. public static XmlReader Create (TextReader input)
  247. {
  248. return Create (input, null);
  249. }
  250. public static XmlReader Create (string inputUri, XmlReaderSettings settings)
  251. {
  252. return Create (inputUri, settings, null);
  253. }
  254. public static XmlReader Create (Stream input, XmlReaderSettings settings)
  255. {
  256. return Create (input, settings, String.Empty);
  257. }
  258. public static XmlReader Create (TextReader input, XmlReaderSettings settings)
  259. {
  260. return Create (input, settings, String.Empty);
  261. }
  262. static XmlReaderSettings PopulateSettings (XmlReaderSettings src)
  263. {
  264. XmlReaderSettings copy;
  265. if (src == null)
  266. copy = new XmlReaderSettings ();
  267. else
  268. copy = src.Clone ();
  269. #if NET_4_5
  270. copy.SetReadOnly ();
  271. #endif
  272. return copy;
  273. }
  274. static XmlReaderSettings PopulateSettings (XmlReader reader, XmlReaderSettings src)
  275. {
  276. XmlReaderSettings copy;
  277. if (src == null)
  278. copy = new XmlReaderSettings ();
  279. else
  280. copy = src.Clone ();
  281. #if NET_4_5
  282. if (reader.Settings != null)
  283. copy.Async = reader.Settings.Async;
  284. copy.SetReadOnly ();
  285. #endif
  286. return copy;
  287. }
  288. public static XmlReader Create (Stream input, XmlReaderSettings settings, string baseUri)
  289. {
  290. settings = PopulateSettings (settings);
  291. return Create (input, settings,
  292. PopulateParserContext (settings, baseUri));
  293. }
  294. public static XmlReader Create (TextReader input, XmlReaderSettings settings, string baseUri)
  295. {
  296. settings = PopulateSettings (settings);
  297. return Create (input, settings,
  298. PopulateParserContext (settings, baseUri));
  299. }
  300. public static XmlReader Create (XmlReader reader, XmlReaderSettings settings)
  301. {
  302. settings = PopulateSettings (reader, settings);
  303. XmlReader r = CreateFilteredXmlReader (reader, settings);
  304. r.settings = settings;
  305. return r;
  306. }
  307. public static XmlReader Create (string inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
  308. {
  309. settings = PopulateSettings (settings);
  310. bool closeInputBak = settings.CloseInput;
  311. try {
  312. settings.CloseInput = true; // forced. See XmlReaderCommonTests.CreateFromUrlClose().
  313. if (inputContext == null)
  314. inputContext = PopulateParserContext (settings, inputUri);
  315. XmlTextReader xtr = new XmlTextReader (false, settings.XmlResolver, inputUri, GetNodeType (settings), inputContext);
  316. XmlReader ret = CreateCustomizedTextReader (xtr, settings);
  317. return ret;
  318. } finally {
  319. settings.CloseInput = closeInputBak;
  320. }
  321. }
  322. public static XmlReader Create (Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
  323. {
  324. settings = PopulateSettings (settings);
  325. if (inputContext == null)
  326. inputContext = PopulateParserContext (settings, String.Empty);
  327. return CreateCustomizedTextReader (new XmlTextReader (input, GetNodeType (settings), inputContext), settings);
  328. }
  329. public static XmlReader Create (TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
  330. {
  331. settings = PopulateSettings (settings);
  332. if (inputContext == null)
  333. inputContext = PopulateParserContext (settings, String.Empty);
  334. return CreateCustomizedTextReader (new XmlTextReader (inputContext.BaseURI, input, GetNodeType (settings), inputContext), settings);
  335. }
  336. private static XmlReader CreateCustomizedTextReader (XmlTextReader reader, XmlReaderSettings settings)
  337. {
  338. reader.XmlResolver = settings.XmlResolver;
  339. // Normalization is set true by default.
  340. reader.Normalization = true;
  341. reader.EntityHandling = EntityHandling.ExpandEntities;
  342. if (settings.ProhibitDtd)
  343. reader.ProhibitDtd = true;
  344. if (!settings.CheckCharacters)
  345. reader.CharacterChecking = false;
  346. // I guess it might be changed in 2.0 RTM to set true
  347. // as default, or just disappear. It goes against
  348. // XmlTextReader's default usage and users will have
  349. // to close input manually (that's annoying). Moreover,
  350. // MS XmlTextReader consumes text input more than
  351. // actually read and users can acquire those extra
  352. // consumption by GetRemainder() that returns different
  353. // TextReader.
  354. reader.CloseInput = settings.CloseInput;
  355. // I would like to support it in detail later;
  356. // MSDN description looks source of confusion. We don't
  357. // need examples, but precise list of how it works.
  358. reader.Conformance = settings.ConformanceLevel;
  359. reader.AdjustLineInfoOffset (settings.LineNumberOffset,
  360. settings.LinePositionOffset);
  361. if (settings.NameTable != null)
  362. reader.SetNameTable (settings.NameTable);
  363. XmlReader r = CreateFilteredXmlReader (reader, settings);
  364. r.settings = settings;
  365. return r;
  366. }
  367. private static XmlReader CreateFilteredXmlReader (XmlReader reader, XmlReaderSettings settings)
  368. {
  369. ConformanceLevel conf = ConformanceLevel.Auto;
  370. if (reader is XmlTextReader)
  371. conf = ((XmlTextReader) reader).Conformance;
  372. else if (reader.Settings != null)
  373. conf = reader.Settings.ConformanceLevel;
  374. else
  375. conf = settings.ConformanceLevel;
  376. if (settings.ConformanceLevel != ConformanceLevel.Auto &&
  377. conf != settings.ConformanceLevel)
  378. throw new InvalidOperationException (String.Format ("ConformanceLevel cannot be overwritten by a wrapping XmlReader. The source reader has {0}, while {1} is specified.", conf, settings.ConformanceLevel));
  379. settings.ConformanceLevel = conf;
  380. reader = CreateValidatingXmlReader (reader, settings);
  381. if ( settings.IgnoreComments ||
  382. settings.IgnoreProcessingInstructions ||
  383. settings.IgnoreWhitespace)
  384. return new XmlFilterReader (reader, settings);
  385. else {
  386. reader.settings = settings;
  387. return reader;
  388. }
  389. }
  390. private static XmlReader CreateValidatingXmlReader (XmlReader reader, XmlReaderSettings settings)
  391. {
  392. XmlValidatingReader xvr = null;
  393. switch (settings.ValidationType) {
  394. // Auto and XDR are obsoleted in 2.0 and therefore ignored.
  395. default:
  396. return reader;
  397. case ValidationType.DTD:
  398. xvr = new XmlValidatingReader (reader);
  399. xvr.XmlResolver = settings.XmlResolver;
  400. xvr.ValidationType = ValidationType.DTD;
  401. break;
  402. case ValidationType.Schema:
  403. return new XmlSchemaValidatingReader (reader, settings);
  404. }
  405. // Actually I don't think they are treated in DTD validation though...
  406. if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessIdentityConstraints) == 0)
  407. throw new NotImplementedException ();
  408. //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0)
  409. // throw new NotImplementedException ();
  410. //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ProcessSchemaLocation) != 0)
  411. // throw new NotImplementedException ();
  412. //if ((settings.ValidationFlags & XmlSchemaValidationFlags.ReportValidationWarnings) == 0)
  413. // throw new NotImplementedException ();
  414. return xvr != null ? xvr : reader;
  415. }
  416. #if NET_4_0
  417. public void Dispose ()
  418. #else
  419. void IDisposable.Dispose()
  420. #endif
  421. {
  422. Dispose (false);
  423. }
  424. protected virtual void Dispose (bool disposing)
  425. {
  426. if (ReadState != ReadState.Closed)
  427. Close ();
  428. }
  429. #endif
  430. public abstract string GetAttribute (int i);
  431. public abstract string GetAttribute (string name);
  432. public abstract string GetAttribute (string name, string namespaceURI);
  433. public static bool IsName (string str)
  434. {
  435. return str != null && XmlChar.IsName (str);
  436. }
  437. public static bool IsNameToken (string str)
  438. {
  439. return str != null && XmlChar.IsNmToken (str);
  440. }
  441. public virtual bool IsStartElement ()
  442. {
  443. return (MoveToContent () == XmlNodeType.Element);
  444. }
  445. public virtual bool IsStartElement (string name)
  446. {
  447. if (!IsStartElement ())
  448. return false;
  449. return (Name == name);
  450. }
  451. public virtual bool IsStartElement (string localname, string ns)
  452. {
  453. if (!IsStartElement ())
  454. return false;
  455. return (LocalName == localname && NamespaceURI == ns);
  456. }
  457. public abstract string LookupNamespace (string prefix);
  458. #if NET_2_0
  459. public virtual void MoveToAttribute (int i)
  460. {
  461. if (i >= AttributeCount)
  462. throw new ArgumentOutOfRangeException ();
  463. MoveToFirstAttribute ();
  464. for (int a = 0; a < i; a++)
  465. MoveToNextAttribute ();
  466. }
  467. #else
  468. public abstract void MoveToAttribute (int i);
  469. #endif
  470. public abstract bool MoveToAttribute (string name);
  471. public abstract bool MoveToAttribute (string name, string ns);
  472. private bool IsContent (XmlNodeType nodeType)
  473. {
  474. /* MS doc says:
  475. * (non-white space text, CDATA, Element, EndElement, EntityReference, or EndEntity)
  476. */
  477. switch (nodeType) {
  478. case XmlNodeType.Text:
  479. return true;
  480. case XmlNodeType.CDATA:
  481. return true;
  482. case XmlNodeType.Element:
  483. return true;
  484. case XmlNodeType.EndElement:
  485. return true;
  486. case XmlNodeType.EntityReference:
  487. return true;
  488. case XmlNodeType.EndEntity:
  489. return true;
  490. }
  491. return false;
  492. }
  493. public virtual XmlNodeType MoveToContent ()
  494. {
  495. switch (ReadState) {
  496. case ReadState.Initial:
  497. case ReadState.Interactive:
  498. break;
  499. default:
  500. return NodeType;
  501. }
  502. if (NodeType == XmlNodeType.Attribute)
  503. MoveToElement ();
  504. do {
  505. if (IsContent (NodeType))
  506. return NodeType;
  507. Read ();
  508. } while (!EOF);
  509. return XmlNodeType.None;
  510. }
  511. public abstract bool MoveToElement ();
  512. public abstract bool MoveToFirstAttribute ();
  513. public abstract bool MoveToNextAttribute ();
  514. public abstract bool Read ();
  515. public abstract bool ReadAttributeValue ();
  516. public virtual string ReadElementString ()
  517. {
  518. if (MoveToContent () != XmlNodeType.Element) {
  519. string error = String.Format ("'{0}' is an invalid node type.",
  520. NodeType.ToString ());
  521. throw XmlError (error);
  522. }
  523. string result = String.Empty;
  524. if (!IsEmptyElement) {
  525. Read ();
  526. result = ReadString ();
  527. if (NodeType != XmlNodeType.EndElement) {
  528. string error = String.Format ("'{0}' is an invalid node type.",
  529. NodeType.ToString ());
  530. throw XmlError (error);
  531. }
  532. }
  533. Read ();
  534. return result;
  535. }
  536. public virtual string ReadElementString (string name)
  537. {
  538. if (MoveToContent () != XmlNodeType.Element) {
  539. string error = String.Format ("'{0}' is an invalid node type.",
  540. NodeType.ToString ());
  541. throw XmlError (error);
  542. }
  543. if (name != Name) {
  544. string error = String.Format ("The {0} tag from namespace {1} is expected.",
  545. Name, NamespaceURI);
  546. throw XmlError (error);
  547. }
  548. string result = String.Empty;
  549. if (!IsEmptyElement) {
  550. Read ();
  551. result = ReadString ();
  552. if (NodeType != XmlNodeType.EndElement) {
  553. string error = String.Format ("'{0}' is an invalid node type.",
  554. NodeType.ToString ());
  555. throw XmlError (error);
  556. }
  557. }
  558. Read ();
  559. return result;
  560. }
  561. public virtual string ReadElementString (string localname, string ns)
  562. {
  563. if (MoveToContent () != XmlNodeType.Element) {
  564. string error = String.Format ("'{0}' is an invalid node type.",
  565. NodeType.ToString ());
  566. throw XmlError (error);
  567. }
  568. if (localname != LocalName || NamespaceURI != ns) {
  569. string error = String.Format ("The {0} tag from namespace {1} is expected.",
  570. LocalName, NamespaceURI);
  571. throw XmlError (error);
  572. }
  573. string result = String.Empty;
  574. if (!IsEmptyElement) {
  575. Read ();
  576. result = ReadString ();
  577. if (NodeType != XmlNodeType.EndElement) {
  578. string error = String.Format ("'{0}' is an invalid node type.",
  579. NodeType.ToString ());
  580. throw XmlError (error);
  581. }
  582. }
  583. Read ();
  584. return result;
  585. }
  586. public virtual void ReadEndElement ()
  587. {
  588. if (MoveToContent () != XmlNodeType.EndElement) {
  589. string error = String.Format ("'{0}' is an invalid node type.",
  590. NodeType.ToString ());
  591. throw XmlError (error);
  592. }
  593. Read ();
  594. }
  595. public virtual string ReadInnerXml ()
  596. {
  597. if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
  598. return String.Empty;
  599. if (IsEmptyElement) {
  600. Read ();
  601. return String.Empty;
  602. }
  603. StringWriter sw = new StringWriter ();
  604. XmlTextWriter xtw = new XmlTextWriter (sw);
  605. if (NodeType == XmlNodeType.Element) {
  606. int startDepth = Depth;
  607. Read ();
  608. while (startDepth < Depth) {
  609. if (ReadState != ReadState.Interactive)
  610. throw XmlError ("Unexpected end of the XML reader.");
  611. xtw.WriteNode (this, false);
  612. }
  613. // reader is now end element, then proceed once more.
  614. Read ();
  615. }
  616. else
  617. xtw.WriteNode (this, false);
  618. return sw.ToString ();
  619. }
  620. public virtual string ReadOuterXml ()
  621. {
  622. if (ReadState != ReadState.Interactive || NodeType == XmlNodeType.EndElement)
  623. return String.Empty;
  624. switch (NodeType) {
  625. case XmlNodeType.Element:
  626. case XmlNodeType.Attribute:
  627. StringWriter sw = new StringWriter ();
  628. XmlTextWriter xtw = new XmlTextWriter (sw);
  629. xtw.WriteNode (this, false);
  630. return sw.ToString ();
  631. default:
  632. Skip ();
  633. return String.Empty;
  634. }
  635. }
  636. public virtual void ReadStartElement ()
  637. {
  638. if (MoveToContent () != XmlNodeType.Element) {
  639. string error = String.Format ("'{0}' is an invalid node type.",
  640. NodeType.ToString ());
  641. throw XmlError (error);
  642. }
  643. Read ();
  644. }
  645. public virtual void ReadStartElement (string name)
  646. {
  647. if (MoveToContent () != XmlNodeType.Element) {
  648. string error = String.Format ("'{0}' is an invalid node type.",
  649. NodeType.ToString ());
  650. throw XmlError (error);
  651. }
  652. if (name != Name) {
  653. string error = String.Format ("The {0} tag from namespace {1} is expected.",
  654. Name, NamespaceURI);
  655. throw XmlError (error);
  656. }
  657. Read ();
  658. }
  659. public virtual void ReadStartElement (string localname, string ns)
  660. {
  661. if (MoveToContent () != XmlNodeType.Element) {
  662. string error = String.Format ("'{0}' is an invalid node type.",
  663. NodeType.ToString ());
  664. throw XmlError (error);
  665. }
  666. if (localname != LocalName || NamespaceURI != ns) {
  667. string error = String.Format ("Expecting {0} tag from namespace {1}, got {2} and {3} instead",
  668. localname, ns,
  669. LocalName, NamespaceURI);
  670. throw XmlError (error);
  671. }
  672. Read ();
  673. }
  674. public virtual string ReadString ()
  675. {
  676. if (readStringBuffer == null)
  677. readStringBuffer = new StringBuilder ();
  678. readStringBuffer.Length = 0;
  679. MoveToElement ();
  680. switch (NodeType) {
  681. default:
  682. return String.Empty;
  683. case XmlNodeType.Element:
  684. if (IsEmptyElement)
  685. return String.Empty;
  686. do {
  687. Read ();
  688. switch (NodeType) {
  689. case XmlNodeType.Text:
  690. case XmlNodeType.CDATA:
  691. case XmlNodeType.Whitespace:
  692. case XmlNodeType.SignificantWhitespace:
  693. readStringBuffer.Append (Value);
  694. continue;
  695. }
  696. break;
  697. } while (true);
  698. break;
  699. case XmlNodeType.Text:
  700. case XmlNodeType.CDATA:
  701. case XmlNodeType.Whitespace:
  702. case XmlNodeType.SignificantWhitespace:
  703. do {
  704. switch (NodeType) {
  705. case XmlNodeType.Text:
  706. case XmlNodeType.CDATA:
  707. case XmlNodeType.Whitespace:
  708. case XmlNodeType.SignificantWhitespace:
  709. readStringBuffer.Append (Value);
  710. Read ();
  711. continue;
  712. }
  713. break;
  714. } while (true);
  715. break;
  716. }
  717. string ret = readStringBuffer.ToString ();
  718. readStringBuffer.Length = 0;
  719. return ret;
  720. }
  721. #if NET_2_0
  722. public virtual Type ValueType {
  723. get { return typeof (string); }
  724. }
  725. public virtual bool ReadToDescendant (string name)
  726. {
  727. if (ReadState == ReadState.Initial) {
  728. MoveToContent ();
  729. if (IsStartElement (name))
  730. return true;
  731. }
  732. if (NodeType != XmlNodeType.Element || IsEmptyElement)
  733. return false;
  734. int depth = Depth;
  735. for (Read (); depth < Depth; Read ())
  736. if (NodeType == XmlNodeType.Element && name == Name)
  737. return true;
  738. return false;
  739. }
  740. public virtual bool ReadToDescendant (string localName, string namespaceURI)
  741. {
  742. if (ReadState == ReadState.Initial) {
  743. MoveToContent ();
  744. if (IsStartElement (localName, namespaceURI))
  745. return true;
  746. }
  747. if (NodeType != XmlNodeType.Element || IsEmptyElement)
  748. return false;
  749. int depth = Depth;
  750. for (Read (); depth < Depth; Read ())
  751. if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
  752. return true;
  753. return false;
  754. }
  755. public virtual bool ReadToFollowing (string name)
  756. {
  757. while (Read ())
  758. if (NodeType == XmlNodeType.Element && name == Name)
  759. return true;
  760. return false;
  761. }
  762. public virtual bool ReadToFollowing (string localName, string namespaceURI)
  763. {
  764. while (Read ())
  765. if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
  766. return true;
  767. return false;
  768. }
  769. public virtual bool ReadToNextSibling (string name)
  770. {
  771. if (ReadState != ReadState.Interactive)
  772. return false;
  773. MoveToElement ();
  774. int depth = Depth;
  775. Skip ();
  776. for (; !EOF && depth <= Depth; Skip ())
  777. if (NodeType == XmlNodeType.Element && name == Name)
  778. return true;
  779. return false;
  780. }
  781. public virtual bool ReadToNextSibling (string localName, string namespaceURI)
  782. {
  783. if (ReadState != ReadState.Interactive)
  784. return false;
  785. int depth = Depth;
  786. Skip ();
  787. for (; !EOF && depth <= Depth; Skip ())
  788. if (NodeType == XmlNodeType.Element && localName == LocalName && namespaceURI == NamespaceURI)
  789. return true;
  790. return false;
  791. }
  792. public virtual XmlReader ReadSubtree ()
  793. {
  794. if (NodeType != XmlNodeType.Element)
  795. throw new InvalidOperationException (String.Format ("ReadSubtree() can be invoked only when the reader is positioned on an element. Current node is {0}. {1}", NodeType, GetLocation ()));
  796. return new SubtreeXmlReader (this);
  797. }
  798. private string ReadContentString ()
  799. {
  800. // The latter condition indicates that this XmlReader is on an attribute value
  801. // (HasAttributes is to indicate it is on attribute value).
  802. if (NodeType == XmlNodeType.Attribute || NodeType != XmlNodeType.Element && HasAttributes)
  803. return Value;
  804. return ReadContentString (true);
  805. }
  806. private string ReadContentString (bool isText)
  807. {
  808. if (isText) {
  809. switch (NodeType) {
  810. case XmlNodeType.Text:
  811. case XmlNodeType.SignificantWhitespace:
  812. case XmlNodeType.Whitespace:
  813. case XmlNodeType.CDATA:
  814. break;
  815. case XmlNodeType.Element:
  816. throw new InvalidOperationException (String.Format ("Node type {0} is not supported in this operation.{1}", NodeType, GetLocation ()));
  817. default:
  818. return String.Empty;
  819. }
  820. }
  821. string value = String.Empty;
  822. do {
  823. switch (NodeType) {
  824. case XmlNodeType.Element:
  825. if (isText)
  826. return value;
  827. throw XmlError ("Child element is not expected in this operation.");
  828. case XmlNodeType.EndElement:
  829. return value;
  830. case XmlNodeType.Text:
  831. case XmlNodeType.CDATA:
  832. case XmlNodeType.SignificantWhitespace:
  833. case XmlNodeType.Whitespace:
  834. value += Value;
  835. break;
  836. }
  837. } while (Read ());
  838. throw XmlError ("Unexpected end of document.");
  839. }
  840. string GetLocation ()
  841. {
  842. IXmlLineInfo li = this as IXmlLineInfo;
  843. return li != null && li.HasLineInfo () ?
  844. String.Format (" {0} (line {1}, column {2})", BaseURI, li.LineNumber, li.LinePosition) : String.Empty;
  845. }
  846. [MonoTODO]
  847. public virtual object ReadElementContentAsObject ()
  848. {
  849. return ReadElementContentAs (ValueType, null);
  850. }
  851. [MonoTODO]
  852. public virtual object ReadElementContentAsObject (string localName, string namespaceURI)
  853. {
  854. return ReadElementContentAs (ValueType, null, localName, namespaceURI);
  855. }
  856. [MonoTODO]
  857. public virtual object ReadContentAsObject ()
  858. {
  859. return ReadContentAs (ValueType, null);
  860. }
  861. #if NET_4_5
  862. public virtual DateTimeOffset ReadContentAsDateTimeOffset ()
  863. {
  864. return XmlConvert.ToDateTimeOffset (ReadContentString ());
  865. }
  866. #endif
  867. public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
  868. {
  869. bool isEmpty = IsEmptyElement;
  870. ReadStartElement ();
  871. object obj = ValueAs (isEmpty ? String.Empty : ReadContentString (false), returnType, namespaceResolver, false);
  872. if (!isEmpty)
  873. ReadEndElement ();
  874. return obj;
  875. }
  876. public virtual object ReadElementContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
  877. {
  878. bool isEmpty = IsEmptyElement;
  879. ReadStartElement (localName, namespaceURI);
  880. if (isEmpty)
  881. return ValueAs (String.Empty, returnType, namespaceResolver, false);
  882. object obj = ReadContentAs (returnType, namespaceResolver);
  883. ReadEndElement ();
  884. return obj;
  885. }
  886. public virtual object ReadContentAs (Type returnType, IXmlNamespaceResolver namespaceResolver)
  887. {
  888. return ValueAs (ReadContentString (), returnType, namespaceResolver, false);
  889. }
  890. private object ValueAs (string text, Type type, IXmlNamespaceResolver resolver, bool isArrayItem)
  891. {
  892. try {
  893. if (type == typeof (object))
  894. return text;
  895. if (type.IsArray && !isArrayItem) {
  896. var elemType = type.GetElementType ();
  897. var sarr = text.Split ((string []) null, StringSplitOptions.RemoveEmptyEntries);
  898. var ret = Array.CreateInstance (elemType, sarr.Length);
  899. for (int i = 0; i < ret.Length; i++)
  900. ret.SetValue (ValueAs (sarr [i], elemType, resolver, true), i);
  901. return ret;
  902. }
  903. if (type == typeof (XmlQualifiedName)) {
  904. if (resolver != null)
  905. return XmlQualifiedName.Parse (text, resolver, true);
  906. else
  907. return XmlQualifiedName.Parse (text, this, true);
  908. }
  909. if (type == typeof (Uri))
  910. return XmlConvert.ToUri (text);
  911. if (type == typeof (TimeSpan))
  912. return XmlConvert.ToTimeSpan (text);
  913. if (type == typeof (DateTimeOffset))
  914. return XmlConvert.ToDateTimeOffset (text);
  915. switch (Type.GetTypeCode (type)) {
  916. case TypeCode.Boolean:
  917. return XQueryConvert.StringToBoolean (text);
  918. case TypeCode.Byte:
  919. return XmlConvert.ToByte (text);
  920. case TypeCode.SByte:
  921. return XmlConvert.ToSByte (text);
  922. case TypeCode.Int16:
  923. return XmlConvert.ToInt16 (text);
  924. case TypeCode.UInt16:
  925. return XQueryConvert.StringToUnsignedShort (text);
  926. case TypeCode.Int32:
  927. return XQueryConvert.StringToInt (text);
  928. case TypeCode.UInt32:
  929. return XQueryConvert.StringToUnsignedInt (text);
  930. case TypeCode.Int64:
  931. return XQueryConvert.StringToInteger (text);
  932. case TypeCode.UInt64:
  933. return XQueryConvert.StringToUnsignedLong (text);
  934. case TypeCode.DateTime:
  935. return XQueryConvert.StringToDateTime (text);
  936. case TypeCode.Decimal:
  937. return XQueryConvert.StringToDecimal (text);
  938. case TypeCode.Double:
  939. return XQueryConvert.StringToDouble (text);
  940. case TypeCode.Single:
  941. return XQueryConvert.StringToFloat (text);
  942. case TypeCode.String:
  943. return text;
  944. }
  945. } catch (Exception ex) {
  946. throw XmlError (String.Format ("Current text value '{0}' is not acceptable for specified type '{1}'. {2}", text, type, ex != null ? ex.Message : String.Empty), ex);
  947. }
  948. throw new ArgumentException (String.Format ("Specified type '{0}' is not supported.", type));
  949. }
  950. public virtual bool ReadElementContentAsBoolean ()
  951. {
  952. try {
  953. return XQueryConvert.StringToBoolean (ReadElementContentAsString ());
  954. } catch (FormatException ex) {
  955. throw XmlError ("Typed value is invalid.", ex);
  956. }
  957. }
  958. public virtual DateTime ReadElementContentAsDateTime ()
  959. {
  960. try {
  961. return XQueryConvert.StringToDateTime (ReadElementContentAsString ());
  962. } catch (FormatException ex) {
  963. throw XmlError ("Typed value is invalid.", ex);
  964. }
  965. }
  966. public virtual decimal ReadElementContentAsDecimal ()
  967. {
  968. try {
  969. return XQueryConvert.StringToDecimal (ReadElementContentAsString ());
  970. } catch (FormatException ex) {
  971. throw XmlError ("Typed value is invalid.", ex);
  972. }
  973. }
  974. public virtual double ReadElementContentAsDouble ()
  975. {
  976. try {
  977. return XQueryConvert.StringToDouble (ReadElementContentAsString ());
  978. } catch (FormatException ex) {
  979. throw XmlError ("Typed value is invalid.", ex);
  980. }
  981. }
  982. public virtual float ReadElementContentAsFloat ()
  983. {
  984. try {
  985. return XQueryConvert.StringToFloat (ReadElementContentAsString ());
  986. } catch (FormatException ex) {
  987. throw XmlError ("Typed value is invalid.", ex);
  988. }
  989. }
  990. public virtual int ReadElementContentAsInt ()
  991. {
  992. try {
  993. return XQueryConvert.StringToInt (ReadElementContentAsString ());
  994. } catch (FormatException ex) {
  995. throw XmlError ("Typed value is invalid.", ex);
  996. }
  997. }
  998. public virtual long ReadElementContentAsLong ()
  999. {
  1000. try {
  1001. return XQueryConvert.StringToInteger (ReadElementContentAsString ());
  1002. } catch (FormatException ex) {
  1003. throw XmlError ("Typed value is invalid.", ex);
  1004. }
  1005. }
  1006. public virtual string ReadElementContentAsString ()
  1007. {
  1008. bool isEmpty = IsEmptyElement;
  1009. // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
  1010. if (NodeType != XmlNodeType.Element)
  1011. throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
  1012. ReadStartElement ();
  1013. if (isEmpty)
  1014. return String.Empty;
  1015. string s = ReadContentString (false);
  1016. ReadEndElement ();
  1017. return s;
  1018. }
  1019. public virtual bool ReadElementContentAsBoolean (string localName, string namespaceURI)
  1020. {
  1021. try {
  1022. return XQueryConvert.StringToBoolean (ReadElementContentAsString (localName, namespaceURI));
  1023. } catch (FormatException ex) {
  1024. throw XmlError ("Typed value is invalid.", ex);
  1025. }
  1026. }
  1027. public virtual DateTime ReadElementContentAsDateTime (string localName, string namespaceURI)
  1028. {
  1029. try {
  1030. return XQueryConvert.StringToDateTime (ReadElementContentAsString (localName, namespaceURI));
  1031. } catch (FormatException ex) {
  1032. throw XmlError ("Typed value is invalid.", ex);
  1033. }
  1034. }
  1035. public virtual decimal ReadElementContentAsDecimal (string localName, string namespaceURI)
  1036. {
  1037. try {
  1038. return XQueryConvert.StringToDecimal (ReadElementContentAsString (localName, namespaceURI));
  1039. } catch (FormatException ex) {
  1040. throw XmlError ("Typed value is invalid.", ex);
  1041. }
  1042. }
  1043. public virtual double ReadElementContentAsDouble (string localName, string namespaceURI)
  1044. {
  1045. try {
  1046. return XQueryConvert.StringToDouble (ReadElementContentAsString (localName, namespaceURI));
  1047. } catch (FormatException ex) {
  1048. throw XmlError ("Typed value is invalid.", ex);
  1049. }
  1050. }
  1051. public virtual float ReadElementContentAsFloat (string localName, string namespaceURI)
  1052. {
  1053. try {
  1054. return XQueryConvert.StringToFloat (ReadElementContentAsString (localName, namespaceURI));
  1055. } catch (FormatException ex) {
  1056. throw XmlError ("Typed value is invalid.", ex);
  1057. }
  1058. }
  1059. public virtual int ReadElementContentAsInt (string localName, string namespaceURI)
  1060. {
  1061. try {
  1062. return XQueryConvert.StringToInt (ReadElementContentAsString (localName, namespaceURI));
  1063. } catch (FormatException ex) {
  1064. throw XmlError ("Typed value is invalid.", ex);
  1065. }
  1066. }
  1067. public virtual long ReadElementContentAsLong (string localName, string namespaceURI)
  1068. {
  1069. try {
  1070. return XQueryConvert.StringToInteger (ReadElementContentAsString (localName, namespaceURI));
  1071. } catch (FormatException ex) {
  1072. throw XmlError ("Typed value is invalid.", ex);
  1073. }
  1074. }
  1075. public virtual string ReadElementContentAsString (string localName, string namespaceURI)
  1076. {
  1077. bool isEmpty = IsEmptyElement;
  1078. // unlike ReadStartElement() it rejects non-content nodes (this check is done before MoveToContent())
  1079. if (NodeType != XmlNodeType.Element)
  1080. throw new InvalidOperationException (String.Format ("'{0}' is an element node.", NodeType));
  1081. ReadStartElement (localName, namespaceURI);
  1082. if (isEmpty)
  1083. return String.Empty;
  1084. string s = ReadContentString (false);
  1085. ReadEndElement ();
  1086. return s;
  1087. }
  1088. public virtual bool ReadContentAsBoolean ()
  1089. {
  1090. try {
  1091. return XQueryConvert.StringToBoolean (ReadContentString ());
  1092. } catch (FormatException ex) {
  1093. throw XmlError ("Typed value is invalid.", ex);
  1094. }
  1095. }
  1096. public virtual DateTime ReadContentAsDateTime ()
  1097. {
  1098. try {
  1099. return XQueryConvert.StringToDateTime (ReadContentString ());
  1100. } catch (FormatException ex) {
  1101. throw XmlError ("Typed value is invalid.", ex);
  1102. }
  1103. }
  1104. public virtual decimal ReadContentAsDecimal ()
  1105. {
  1106. try {
  1107. return XQueryConvert.StringToDecimal (ReadContentString ());
  1108. } catch (FormatException ex) {
  1109. throw XmlError ("Typed value is invalid.", ex);
  1110. }
  1111. }
  1112. public virtual double ReadContentAsDouble ()
  1113. {
  1114. try {
  1115. return XQueryConvert.StringToDouble (ReadContentString ());
  1116. } catch (FormatException ex) {
  1117. throw XmlError ("Typed value is invalid.", ex);
  1118. }
  1119. }
  1120. public virtual float ReadContentAsFloat ()
  1121. {
  1122. try {
  1123. return XQueryConvert.StringToFloat (ReadContentString ());
  1124. } catch (FormatException ex) {
  1125. throw XmlError ("Typed value is invalid.", ex);
  1126. }
  1127. }
  1128. public virtual int ReadContentAsInt ()
  1129. {
  1130. try {
  1131. return XQueryConvert.StringToInt (ReadContentString ());
  1132. } catch (FormatException ex) {
  1133. throw XmlError ("Typed value is invalid.", ex);
  1134. }
  1135. }
  1136. public virtual long ReadContentAsLong ()
  1137. {
  1138. try {
  1139. return XQueryConvert.StringToInteger (ReadContentString ());
  1140. } catch (FormatException ex) {
  1141. throw XmlError ("Typed value is invalid.", ex);
  1142. }
  1143. }
  1144. public virtual string ReadContentAsString ()
  1145. {
  1146. return ReadContentString ();
  1147. }
  1148. public virtual int ReadContentAsBase64 (
  1149. byte [] buffer, int index, int count)
  1150. {
  1151. CheckSupport ();
  1152. return binary.ReadContentAsBase64 (
  1153. buffer, index, count);
  1154. }
  1155. public virtual int ReadContentAsBinHex (
  1156. byte [] buffer, int index, int count)
  1157. {
  1158. CheckSupport ();
  1159. return binary.ReadContentAsBinHex (
  1160. buffer, index, count);
  1161. }
  1162. public virtual int ReadElementContentAsBase64 (
  1163. byte [] buffer, int index, int count)
  1164. {
  1165. CheckSupport ();
  1166. return binary.ReadElementContentAsBase64 (
  1167. buffer, index, count);
  1168. }
  1169. public virtual int ReadElementContentAsBinHex (
  1170. byte [] buffer, int index, int count)
  1171. {
  1172. CheckSupport ();
  1173. return binary.ReadElementContentAsBinHex (
  1174. buffer, index, count);
  1175. }
  1176. private void CheckSupport ()
  1177. {
  1178. // Default implementation expects both.
  1179. if (!CanReadBinaryContent || !CanReadValueChunk)
  1180. throw new NotSupportedException ();
  1181. if (binary == null)
  1182. binary = new XmlReaderBinarySupport (this);
  1183. }
  1184. #endif
  1185. public virtual int ReadValueChunk (char [] buffer, int index, int count)
  1186. {
  1187. if (!CanReadValueChunk)
  1188. throw new NotSupportedException ();
  1189. if (binary == null)
  1190. binary = new XmlReaderBinarySupport (this);
  1191. return binary.ReadValueChunk (buffer, index, count);
  1192. }
  1193. public abstract void ResolveEntity ();
  1194. public virtual void Skip ()
  1195. {
  1196. if (ReadState != ReadState.Interactive)
  1197. return;
  1198. MoveToElement ();
  1199. if (NodeType != XmlNodeType.Element || IsEmptyElement) {
  1200. Read ();
  1201. return;
  1202. }
  1203. int depth = Depth;
  1204. while (Read () && depth < Depth)
  1205. ;
  1206. if (NodeType == XmlNodeType.EndElement)
  1207. Read ();
  1208. }
  1209. private XmlException XmlError (string message)
  1210. {
  1211. return new XmlException (this as IXmlLineInfo, BaseURI, message);
  1212. }
  1213. #if NET_2_0
  1214. private XmlException XmlError (string message, Exception innerException)
  1215. {
  1216. return new XmlException (this as IXmlLineInfo, BaseURI, message);
  1217. }
  1218. #endif
  1219. #endregion
  1220. #if NET_4_5
  1221. #region .NET 4.5 Async Methods
  1222. bool asyncRunning;
  1223. void StartAsync ()
  1224. {
  1225. if (!settings.Async)
  1226. throw new InvalidOperationException ("Set XmlReaderSettings.Async to true if you want to use Async Methods.");
  1227. lock (this) {
  1228. if (asyncRunning)
  1229. throw new InvalidOperationException ("An asynchronous operation is already in progress.");
  1230. asyncRunning = true;
  1231. }
  1232. }
  1233. public virtual Task<bool> ReadAsync ()
  1234. {
  1235. StartAsync ();
  1236. return Task.Run (() => {
  1237. try {
  1238. return Read ();
  1239. } finally {
  1240. asyncRunning = false;
  1241. }
  1242. });
  1243. }
  1244. public virtual Task<string> GetValueAsync ()
  1245. {
  1246. StartAsync ();
  1247. return Task.Run (() => {
  1248. try {
  1249. return Value;
  1250. } finally {
  1251. asyncRunning = false;
  1252. }
  1253. });
  1254. }
  1255. public virtual Task<string> ReadInnerXmlAsync ()
  1256. {
  1257. StartAsync ();
  1258. return Task.Run (() => {
  1259. try {
  1260. return ReadInnerXml ();
  1261. } finally {
  1262. asyncRunning = false;
  1263. }
  1264. });
  1265. }
  1266. public virtual Task<string> ReadOuterXmlAsync ()
  1267. {
  1268. StartAsync ();
  1269. return Task.Run (() => {
  1270. try {
  1271. return ReadOuterXml ();
  1272. } finally {
  1273. asyncRunning = false;
  1274. }
  1275. });
  1276. }
  1277. public virtual Task<string> ReadContentAsStringAsync ()
  1278. {
  1279. StartAsync ();
  1280. return Task.Run (() => {
  1281. try {
  1282. return ReadContentAsString ();
  1283. } finally {
  1284. asyncRunning = false;
  1285. }
  1286. });
  1287. }
  1288. public virtual Task<int> ReadContentAsBase64Async (byte[] buffer, int index, int count)
  1289. {
  1290. StartAsync ();
  1291. return Task.Run (() => {
  1292. try {
  1293. return ReadContentAsBase64 (buffer, index, count);
  1294. } finally {
  1295. asyncRunning = false;
  1296. }
  1297. });
  1298. }
  1299. public virtual Task<int> ReadContentAsBinHexAsync (byte[] buffer, int index, int count)
  1300. {
  1301. StartAsync ();
  1302. return Task.Run (() => {
  1303. try {
  1304. return ReadContentAsBinHex (buffer, index, count);
  1305. } finally {
  1306. asyncRunning = false;
  1307. }
  1308. });
  1309. }
  1310. public virtual Task<int> ReadElementContentAsBase64Async (byte[] buffer, int index, int count)
  1311. {
  1312. StartAsync ();
  1313. return Task.Run (() => {
  1314. try {
  1315. return ReadElementContentAsBase64 (buffer, index, count);
  1316. } finally {
  1317. asyncRunning = false;
  1318. }
  1319. });
  1320. }
  1321. public virtual Task<int> ReadElementContentAsBinHexAsync (byte[] buffer, int index, int count)
  1322. {
  1323. StartAsync ();
  1324. return Task.Run (() => {
  1325. try {
  1326. return ReadElementContentAsBinHex (buffer, index, count);
  1327. } finally {
  1328. asyncRunning = false;
  1329. }
  1330. });
  1331. }
  1332. public virtual Task<int> ReadValueChunkAsync (char[] buffer, int index, int count)
  1333. {
  1334. StartAsync ();
  1335. return Task.Run (() => {
  1336. try {
  1337. return ReadValueChunk (buffer, index, count);
  1338. } finally {
  1339. asyncRunning = false;
  1340. }
  1341. });
  1342. }
  1343. public virtual Task<object> ReadContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
  1344. {
  1345. StartAsync ();
  1346. return Task.Run (() => {
  1347. try {
  1348. return ReadContentAs (returnType, namespaceResolver);
  1349. } finally {
  1350. asyncRunning = false;
  1351. }
  1352. });
  1353. }
  1354. public virtual Task<object> ReadContentAsObjectAsync ()
  1355. {
  1356. StartAsync ();
  1357. return Task.Run (() => {
  1358. try {
  1359. return ReadContentAsObject ();
  1360. } finally {
  1361. asyncRunning = false;
  1362. }
  1363. });
  1364. }
  1365. public virtual Task<object> ReadElementContentAsAsync (Type returnType, IXmlNamespaceResolver namespaceResolver)
  1366. {
  1367. StartAsync ();
  1368. return Task.Run (() => {
  1369. try {
  1370. return ReadElementContentAs (returnType, namespaceResolver);
  1371. } finally {
  1372. asyncRunning = false;
  1373. }
  1374. });
  1375. }
  1376. public virtual Task<object> ReadElementContentAsObjectAsync ()
  1377. {
  1378. StartAsync ();
  1379. return Task.Run (() => {
  1380. try {
  1381. return ReadElementContentAsObject ();
  1382. } finally {
  1383. asyncRunning = false;
  1384. }
  1385. });
  1386. }
  1387. public virtual Task<string> ReadElementContentAsStringAsync ()
  1388. {
  1389. StartAsync ();
  1390. return Task.Run (() => {
  1391. try {
  1392. return ReadElementContentAsString ();
  1393. } finally {
  1394. asyncRunning = false;
  1395. }
  1396. });
  1397. }
  1398. public virtual Task<XmlNodeType> MoveToContentAsync ()
  1399. {
  1400. StartAsync ();
  1401. return Task.Run (() => {
  1402. try {
  1403. return MoveToContent ();
  1404. } finally {
  1405. asyncRunning = false;
  1406. }
  1407. });
  1408. }
  1409. public virtual Task SkipAsync ()
  1410. {
  1411. StartAsync ();
  1412. return Task.Run (() => {
  1413. try {
  1414. Skip ();
  1415. } finally {
  1416. asyncRunning = false;
  1417. }
  1418. });
  1419. }
  1420. #endregion
  1421. #endif
  1422. }
  1423. }