XmlNodeReaderImpl.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. //
  2. // System.Xml.XmlNodeReaderImpl.cs - implements the core part of XmlNodeReader
  3. //
  4. // Author:
  5. // Atsushi Enomoto ([email protected])
  6. //
  7. // (C) 2004 Novell Inc.
  8. //
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. //
  30. // This serves the implementation part of XmlNodeReader except for
  31. // ResolveEntity().
  32. //
  33. using System;
  34. using System.Collections;
  35. using System.Xml;
  36. using System.Text;
  37. using Mono.Xml;
  38. #if NET_2_0
  39. using System.Xml.Schema;
  40. #endif
  41. namespace System.Xml
  42. {
  43. #if NET_2_0
  44. internal class XmlNodeReaderImpl : XmlReader, IHasXmlParserContext, IXmlNamespaceResolver
  45. #else
  46. internal class XmlNodeReaderImpl : XmlReader, IHasXmlParserContext
  47. #endif
  48. {
  49. XmlDocument document;
  50. XmlNode startNode;
  51. XmlNode current;
  52. ReadState state = ReadState.Initial;
  53. int depth;
  54. bool isEndElement;
  55. bool alreadyRead;
  56. private XmlNode ownerLinkedNode {
  57. get {
  58. if (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute)
  59. return ((XmlAttribute) current.ParentNode).OwnerElement;
  60. else if (current.NodeType == XmlNodeType.Attribute)
  61. return ((XmlAttribute) current).OwnerElement;
  62. else
  63. return current;
  64. }
  65. }
  66. #region Constructor
  67. internal XmlNodeReaderImpl (XmlNodeReaderImpl entityContainer)
  68. : this (entityContainer.current)
  69. {
  70. }
  71. public XmlNodeReaderImpl (XmlNode node)
  72. {
  73. startNode = node;
  74. depth = 0;
  75. document = startNode.NodeType == XmlNodeType.Document ?
  76. startNode as XmlDocument : startNode.OwnerDocument;
  77. switch (node.NodeType) {
  78. case XmlNodeType.Document:
  79. case XmlNodeType.DocumentFragment:
  80. case XmlNodeType.EntityReference:
  81. break;
  82. default:
  83. alreadyRead = true;
  84. break;
  85. }
  86. }
  87. #endregion
  88. #region Properties
  89. public override int AttributeCount {
  90. get {
  91. if (state != ReadState.Interactive)
  92. return 0;
  93. if (isEndElement || current == null)
  94. return 0;
  95. XmlNode n = ownerLinkedNode;
  96. return n.Attributes != null ? n.Attributes.Count : 0;
  97. }
  98. }
  99. public override string BaseURI {
  100. get {
  101. if (current == null)
  102. return startNode.BaseURI;
  103. return current.BaseURI;
  104. }
  105. }
  106. #if NET_2_0
  107. public override bool CanReadBinaryContent {
  108. get { return true; }
  109. }
  110. public override bool CanReadValueChunk {
  111. get { return true; }
  112. }
  113. #else
  114. internal override bool CanReadBinaryContent {
  115. get { return true; }
  116. }
  117. internal override bool CanReadValueChunk {
  118. get { return true; }
  119. }
  120. #endif
  121. public override bool CanResolveEntity {
  122. get { return false; }
  123. }
  124. public override int Depth {
  125. get {
  126. if (current == null)
  127. return 0;
  128. if (current.NodeType == XmlNodeType.Attribute)
  129. return depth + 1;
  130. if (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute)
  131. return depth + 2;
  132. return depth;
  133. }
  134. }
  135. public override bool EOF {
  136. get {
  137. return this.ReadState == ReadState.EndOfFile
  138. || this.ReadState == ReadState.Error;
  139. }
  140. }
  141. public override bool HasAttributes {
  142. get {
  143. if (isEndElement || current == null)
  144. return false;
  145. // MS BUG: inconsistent return value between XmlTextReader and XmlNodeReader.
  146. // As for attribute and its descendants, XmlReader returns element's HasAttributes.
  147. XmlNode n = ownerLinkedNode;
  148. if (n.Attributes == null ||
  149. n.Attributes.Count == 0)
  150. return false;
  151. else
  152. return true;
  153. }
  154. }
  155. public override bool HasValue {
  156. get {
  157. if (current == null)
  158. return false;
  159. switch (current.NodeType) {
  160. case XmlNodeType.Element:
  161. case XmlNodeType.EntityReference:
  162. case XmlNodeType.Document:
  163. case XmlNodeType.DocumentFragment:
  164. case XmlNodeType.Notation:
  165. case XmlNodeType.EndElement:
  166. case XmlNodeType.EndEntity:
  167. return false;
  168. default:
  169. return true;
  170. }
  171. }
  172. }
  173. public override bool IsDefault {
  174. get {
  175. if (current == null)
  176. return false;
  177. if (current.NodeType != XmlNodeType.Attribute)
  178. return false;
  179. else
  180. {
  181. return !((XmlAttribute) current).Specified;
  182. }
  183. }
  184. }
  185. public override bool IsEmptyElement {
  186. get {
  187. if (current == null)
  188. return false;
  189. if(current.NodeType == XmlNodeType.Element)
  190. return ((XmlElement) current).IsEmpty;
  191. else
  192. return false;
  193. }
  194. }
  195. #if NET_2_0
  196. #else
  197. public override string this [int i] {
  198. get { return GetAttribute (i); }
  199. }
  200. public override string this [string name] {
  201. get { return GetAttribute (name); }
  202. }
  203. public override string this [string name, string namespaceURI] {
  204. get { return GetAttribute (name, namespaceURI); }
  205. }
  206. #endif
  207. public override string LocalName {
  208. get {
  209. if (current == null)
  210. return String.Empty;
  211. switch (current.NodeType) {
  212. case XmlNodeType.Attribute:
  213. case XmlNodeType.DocumentType:
  214. case XmlNodeType.Element:
  215. case XmlNodeType.EntityReference:
  216. case XmlNodeType.ProcessingInstruction:
  217. case XmlNodeType.XmlDeclaration:
  218. return current.LocalName;
  219. }
  220. return String.Empty;
  221. }
  222. }
  223. public override string Name {
  224. get {
  225. if (current == null)
  226. return String.Empty;
  227. switch (current.NodeType) {
  228. case XmlNodeType.Attribute:
  229. case XmlNodeType.DocumentType:
  230. case XmlNodeType.Element:
  231. case XmlNodeType.EntityReference:
  232. case XmlNodeType.ProcessingInstruction:
  233. case XmlNodeType.XmlDeclaration:
  234. return current.Name;
  235. }
  236. return String.Empty;
  237. }
  238. }
  239. public override string NamespaceURI {
  240. get {
  241. if (current == null)
  242. return String.Empty;
  243. return current.NamespaceURI;
  244. }
  245. }
  246. public override XmlNameTable NameTable {
  247. get { return document.NameTable; }
  248. }
  249. public override XmlNodeType NodeType {
  250. get {
  251. if (current == null)
  252. return XmlNodeType.None;
  253. return isEndElement ? XmlNodeType.EndElement : current.NodeType;
  254. }
  255. }
  256. public override string Prefix {
  257. get {
  258. if (current == null)
  259. return String.Empty;
  260. return current.Prefix;
  261. }
  262. }
  263. #if NET_2_0
  264. #else
  265. public override char QuoteChar {
  266. get {
  267. return '"';
  268. }
  269. }
  270. #endif
  271. public override ReadState ReadState {
  272. get { return state; }
  273. }
  274. #if NET_2_0
  275. public override IXmlSchemaInfo SchemaInfo {
  276. get { return current != null ? current.SchemaInfo : null; }
  277. }
  278. #endif
  279. public override string Value {
  280. get {
  281. if (NodeType == XmlNodeType.DocumentType)
  282. return ((XmlDocumentType) current).InternalSubset;
  283. else
  284. return HasValue ? current.Value : String.Empty;
  285. }
  286. }
  287. public override string XmlLang {
  288. get {
  289. if (current == null)
  290. return startNode.XmlLang;
  291. return current.XmlLang;
  292. }
  293. }
  294. public override XmlSpace XmlSpace {
  295. get {
  296. if (current == null)
  297. return startNode.XmlSpace;
  298. return current.XmlSpace;
  299. }
  300. }
  301. #endregion
  302. #region Methods
  303. public override void Close ()
  304. {
  305. current = null;
  306. state = ReadState.Closed;
  307. }
  308. public override string GetAttribute (int attributeIndex)
  309. {
  310. if (NodeType == XmlNodeType.XmlDeclaration) {
  311. XmlDeclaration decl = current as XmlDeclaration;
  312. if (attributeIndex == 0)
  313. return decl.Version;
  314. else if (attributeIndex == 1) {
  315. if (decl.Encoding != String.Empty)
  316. return decl.Encoding;
  317. else if (decl.Standalone != String.Empty)
  318. return decl.Standalone;
  319. }
  320. else if (attributeIndex == 2 &&
  321. decl.Encoding != String.Empty && decl.Standalone != null)
  322. return decl.Standalone;
  323. throw new ArgumentOutOfRangeException ("Index out of range.");
  324. } else if (NodeType == XmlNodeType.DocumentType) {
  325. XmlDocumentType doctype = current as XmlDocumentType;
  326. if (attributeIndex == 0) {
  327. if (doctype.PublicId != "")
  328. return doctype.PublicId;
  329. else if (doctype.SystemId != "")
  330. return doctype.SystemId;
  331. } else if (attributeIndex == 1)
  332. if (doctype.PublicId == "" && doctype.SystemId != "")
  333. return doctype.SystemId;
  334. throw new ArgumentOutOfRangeException ("Index out of range.");
  335. }
  336. // This is MS.NET bug which returns attributes in spite of EndElement.
  337. if (isEndElement || current == null)
  338. return null;
  339. if (attributeIndex < 0 || attributeIndex > AttributeCount)
  340. throw new ArgumentOutOfRangeException ("Index out of range.");
  341. return ownerLinkedNode.Attributes [attributeIndex].Value;
  342. }
  343. public override string GetAttribute (string name)
  344. {
  345. // This is MS.NET bug which returns attributes in spite of EndElement.
  346. if (isEndElement || current == null)
  347. return null;
  348. if (NodeType == XmlNodeType.XmlDeclaration)
  349. return GetXmlDeclarationAttribute (name);
  350. else if (NodeType == XmlNodeType.DocumentType)
  351. return GetDocumentTypeAttribute (name);
  352. if (ownerLinkedNode.Attributes == null)
  353. return null;
  354. XmlAttribute attr = ownerLinkedNode.Attributes [name];
  355. if (attr == null)
  356. return null;
  357. else
  358. return attr.Value;
  359. }
  360. public override string GetAttribute (string name, string namespaceURI)
  361. {
  362. // This is MS.NET bug which returns attributes in spite of EndElement.
  363. if (isEndElement || current == null)
  364. return null;
  365. if (NodeType == XmlNodeType.XmlDeclaration)
  366. return GetXmlDeclarationAttribute (name);
  367. else if (NodeType == XmlNodeType.DocumentType)
  368. return GetDocumentTypeAttribute (name);
  369. if (ownerLinkedNode.Attributes == null)
  370. return null;
  371. XmlAttribute attr = ownerLinkedNode.Attributes [name, namespaceURI];
  372. if (attr == null)
  373. return null; // In fact MS.NET returns null instead of String.Empty.
  374. else
  375. return attr.Value;
  376. }
  377. private string GetXmlDeclarationAttribute (string name)
  378. {
  379. XmlDeclaration decl = current as XmlDeclaration;
  380. switch (name) {
  381. case "version":
  382. return decl.Version;
  383. case "encoding":
  384. // This is MS.NET bug that XmlNodeReturns in case of string.empty.
  385. return decl.Encoding != String.Empty ? decl.Encoding : null;
  386. case "standalone":
  387. return decl.Standalone;
  388. }
  389. return null;
  390. }
  391. private string GetDocumentTypeAttribute (string name)
  392. {
  393. XmlDocumentType doctype = current as XmlDocumentType;
  394. switch (name) {
  395. case "PUBLIC":
  396. return doctype.PublicId;
  397. case "SYSTEM":
  398. return doctype.SystemId;
  399. }
  400. return null;
  401. }
  402. XmlParserContext IHasXmlParserContext.ParserContext {
  403. get {
  404. return new XmlParserContext (document.NameTable,
  405. current.ConstructNamespaceManager (),
  406. document.DocumentType != null ? document.DocumentType.DTD : null,
  407. current.BaseURI, XmlLang, XmlSpace, Encoding.Unicode);
  408. }
  409. }
  410. #if NET_2_0
  411. public IDictionary GetNamespacesInScope (XmlNamespaceScope scope)
  412. {
  413. Hashtable table = new Hashtable ();
  414. XmlNode n = current;
  415. do {
  416. if (n.NodeType == XmlNodeType.Document)
  417. break;
  418. for (int i = 0; i < current.Attributes.Count; i++) {
  419. XmlAttribute a = current.Attributes [i];
  420. if (a.NamespaceURI == XmlNamespaceManager.XmlnsXmlns)
  421. table.Add (a.Prefix == XmlNamespaceManager.PrefixXmlns ? a.LocalName : String.Empty, a.Value);
  422. }
  423. if (scope == XmlNamespaceScope.Local)
  424. return table;
  425. n = n.ParentNode;
  426. } while (n != null);
  427. if (scope == XmlNamespaceScope.All)
  428. table.Add (XmlNamespaceManager.PrefixXml, XmlNamespaceManager.XmlnsXml);
  429. return table;
  430. }
  431. #endif
  432. private XmlElement GetCurrentElement ()
  433. {
  434. XmlElement el = null;
  435. switch (current.NodeType) {
  436. case XmlNodeType.Attribute:
  437. el = ((XmlAttribute) current).OwnerElement;
  438. break;
  439. case XmlNodeType.Element:
  440. el = (XmlElement) current;
  441. break;
  442. case XmlNodeType.Text:
  443. case XmlNodeType.CDATA:
  444. case XmlNodeType.EntityReference:
  445. case XmlNodeType.Comment:
  446. case XmlNodeType.SignificantWhitespace:
  447. case XmlNodeType.Whitespace:
  448. case XmlNodeType.ProcessingInstruction:
  449. el = current.ParentNode as XmlElement;
  450. break;
  451. }
  452. return el;
  453. }
  454. public override string LookupNamespace (string prefix)
  455. {
  456. if (current == null)
  457. return null;
  458. XmlElement el = GetCurrentElement ();
  459. for (; el != null; el = el.ParentNode as XmlElement) {
  460. for (int i = 0; i < el.Attributes.Count; i++) {
  461. XmlAttribute attr = el.Attributes [i];
  462. if (attr.NamespaceURI != XmlNamespaceManager.XmlnsXmlns)
  463. continue;
  464. if (prefix == "") {
  465. if (attr.Prefix == "")
  466. return attr.Value;
  467. }
  468. else if (attr.LocalName == prefix)
  469. return attr.Value;
  470. continue;
  471. }
  472. }
  473. switch (prefix) {
  474. case XmlNamespaceManager.PrefixXml:
  475. return XmlNamespaceManager.XmlnsXml;
  476. case XmlNamespaceManager.PrefixXmlns:
  477. return XmlNamespaceManager.XmlnsXmlns;
  478. }
  479. return null;
  480. }
  481. #if NET_2_0
  482. public string LookupPrefix (string ns)
  483. {
  484. return LookupPrefix (ns, false);
  485. }
  486. public string LookupPrefix (string ns, bool atomizedNames)
  487. {
  488. if (current == null)
  489. return null;
  490. XmlElement el = GetCurrentElement ();
  491. for (; el != null; el = el.ParentNode as XmlElement) {
  492. for (int i = 0; i < el.Attributes.Count; i++) {
  493. XmlAttribute attr = el.Attributes [i];
  494. if (atomizedNames) {
  495. if (!Object.ReferenceEquals (attr.NamespaceURI, XmlNamespaceManager.XmlnsXmlns))
  496. continue;
  497. if (Object.ReferenceEquals (attr.Value, ns))
  498. // xmlns:blah="..." -> LocalName, xmlns="..." -> String.Empty
  499. return attr.Prefix != String.Empty ? attr.LocalName : String.Empty;
  500. } else {
  501. if (attr.NamespaceURI != XmlNamespaceManager.XmlnsXmlns)
  502. continue;
  503. if (attr.Value == ns)
  504. // xmlns:blah="..." -> LocalName, xmlns="..." -> String.Empty
  505. return attr.Prefix != String.Empty ? attr.LocalName : String.Empty;
  506. }
  507. }
  508. }
  509. switch (ns) {
  510. case XmlNamespaceManager.XmlnsXml:
  511. return XmlNamespaceManager.PrefixXml;
  512. case XmlNamespaceManager.XmlnsXmlns:
  513. return XmlNamespaceManager.PrefixXmlns;
  514. }
  515. return null;
  516. }
  517. #endif
  518. public override void MoveToAttribute (int attributeIndex)
  519. {
  520. if (isEndElement || attributeIndex < 0 || attributeIndex > AttributeCount)
  521. throw new ArgumentOutOfRangeException ();
  522. state = ReadState.Interactive;
  523. current = ownerLinkedNode.Attributes [attributeIndex];
  524. }
  525. public override bool MoveToAttribute (string name)
  526. {
  527. if (isEndElement || current == null)
  528. return false;
  529. XmlNode tmpCurrent = current;
  530. if (current.ParentNode.NodeType == XmlNodeType.Attribute)
  531. current = current.ParentNode;
  532. if (ownerLinkedNode.Attributes == null)
  533. return false;
  534. XmlAttribute attr = ownerLinkedNode.Attributes [name];
  535. if (attr == null) {
  536. current = tmpCurrent;
  537. return false;
  538. }
  539. else {
  540. current = attr;
  541. return true;
  542. }
  543. }
  544. public override bool MoveToAttribute (string name, string namespaceURI)
  545. {
  546. if (isEndElement || current == null)
  547. return false;
  548. if (ownerLinkedNode.Attributes == null)
  549. return false;
  550. XmlAttribute attr = ownerLinkedNode.Attributes [name, namespaceURI];
  551. if (attr == null)
  552. return false;
  553. else {
  554. current = attr;
  555. return true;
  556. }
  557. }
  558. private void MoveToParentElement ()
  559. {
  560. // This is buggy. It is not only the case when EndElement = true.
  561. isEndElement = true;
  562. depth--;
  563. current = current.ParentNode;
  564. }
  565. public override bool MoveToElement ()
  566. {
  567. if (current == null)
  568. return false;
  569. XmlNode n = ownerLinkedNode;
  570. if (current != n) {
  571. current = n;
  572. return true;
  573. } else
  574. return false;
  575. }
  576. public override bool MoveToFirstAttribute ()
  577. {
  578. if (current == null)
  579. return false;
  580. if (ownerLinkedNode.Attributes == null)
  581. return false;
  582. if(ownerLinkedNode.Attributes.Count > 0)
  583. {
  584. current = ownerLinkedNode.Attributes [0];
  585. return true;
  586. }
  587. else
  588. return false;
  589. }
  590. public override bool MoveToNextAttribute ()
  591. {
  592. if (current == null)
  593. return false;
  594. if (current.NodeType != XmlNodeType.Attribute)
  595. return MoveToFirstAttribute ();
  596. else
  597. {
  598. XmlAttributeCollection ac = ((XmlAttribute) current).OwnerElement.Attributes;
  599. for (int i=0; i<ac.Count-1; i++)
  600. {
  601. XmlAttribute attr = ac [i];
  602. if (attr == current)
  603. {
  604. i++;
  605. if (i == ac.Count)
  606. return false;
  607. current = ac [i];
  608. return true;
  609. }
  610. }
  611. return false;
  612. }
  613. }
  614. private bool MoveToNextSibling ()
  615. {
  616. if (alreadyRead) {
  617. alreadyRead = false;
  618. return current != null;
  619. }
  620. if (current.NextSibling != null) {
  621. isEndElement = false;
  622. current = current.NextSibling;
  623. } else {
  624. MoveToParentElement ();
  625. }
  626. if (current == null) {
  627. state = ReadState.EndOfFile;
  628. return false;
  629. }
  630. else
  631. return true;
  632. }
  633. public override bool Read ()
  634. {
  635. if (EOF)
  636. return false;
  637. #if NET_2_0
  638. if (Binary != null)
  639. Binary.Reset ();
  640. #endif
  641. if (ReadState == ReadState.Initial) {
  642. current = startNode;
  643. state = ReadState.Interactive;
  644. // when startNode is document or fragment
  645. if (!alreadyRead)
  646. current = startNode.FirstChild;
  647. else
  648. alreadyRead = false;
  649. if (current == null) {
  650. state = ReadState.Error;
  651. return false;
  652. } else
  653. return true;
  654. }
  655. MoveToElement ();
  656. if (alreadyRead) {
  657. alreadyRead = false;
  658. return current != null;
  659. }
  660. bool isEnd = false;
  661. if (IsEmptyElement || isEndElement) {
  662. // Then go up and move to next.
  663. // If no more nodes, then set EOF.
  664. isEndElement = false;
  665. if (current.ParentNode == null
  666. || current.ParentNode.NodeType == XmlNodeType.Document
  667. || current.ParentNode.NodeType == XmlNodeType.DocumentFragment) {
  668. isEnd = true;
  669. } else if (current.NextSibling == null) {
  670. depth--;
  671. current = current.ParentNode;
  672. isEndElement = true;
  673. return true;
  674. } else {
  675. current = current.NextSibling;
  676. return true;
  677. }
  678. }
  679. if (current.NextSibling == null
  680. && current.ParentNode is XmlEntityReference)
  681. isEnd = true;
  682. if (isEnd) {
  683. current = null;
  684. state = ReadState.EndOfFile;
  685. return false;
  686. }
  687. if (!isEndElement && current.FirstChild != null && current.NodeType != XmlNodeType.EntityReference) {
  688. isEndElement = false;
  689. current = current.FirstChild;
  690. depth++;
  691. } else if (current.NodeType == XmlNodeType.Element) {
  692. isEndElement = true;
  693. if (current.FirstChild != null)
  694. depth--;
  695. } else
  696. MoveToNextSibling ();
  697. return current != null;
  698. }
  699. public override bool ReadAttributeValue ()
  700. {
  701. if (current.NodeType == XmlNodeType.Attribute) {
  702. if (current.FirstChild == null)
  703. return false;
  704. current = current.FirstChild;
  705. return true;
  706. } else if (current.ParentNode.NodeType == XmlNodeType.Attribute) {
  707. if (current.NextSibling == null)
  708. return false;
  709. current = current.NextSibling;
  710. return true;
  711. } else
  712. return false;
  713. }
  714. #if NET_1_0
  715. public override string ReadInnerXml ()
  716. {
  717. return ReadInnerXmlInternal ();
  718. }
  719. public override string ReadOuterXml ()
  720. {
  721. return ReadOuterXmlInternal ();
  722. }
  723. #endif
  724. public override string ReadString ()
  725. {
  726. return ReadStringInternal ();
  727. }
  728. public override void ResolveEntity ()
  729. {
  730. throw new NotSupportedException ("Should not happen.");
  731. }
  732. public override void Skip ()
  733. {
  734. // Why is this overriden? Such skipping might raise
  735. // (or ignore) unexpected validation error.
  736. base.Skip ();
  737. }
  738. #endregion
  739. }
  740. }