public override bool Read() { // First call to Read if (ReadState == System.Xml.ReadState.Initial) { var rootNode = this.document.Root; this.nodeStack.Push(rootNode); currentNode = rootNode.FirstChild; return(CheckReadStateAndReturn()); } if (xmlReader != null) { var result = xmlReader.Read(); if (result && xmlReader.Depth > 0) { return(result); } else { xmlReader.Close(); textReader.Dispose(); xmlReader = null; textReader = null; } } switch (traverseDirection) { case TraverseDirection.Down: // As long as there're children go down (depth first) if (currentNode.HasChildren) { nodeStack.Push(currentNode); currentNode = currentNode.FirstChild; } else { var parent = nodeStack.Peek(); using (var lastChild = parent.LastChild) { if (currentNode.IsSame(lastChild)) { // Time to move back up nodeStack.Pop(); traverseDirection = TraverseDirection.Up; currentNode.Dispose(); currentNode = parent; } else { // There're still siblings left to visit var nextSibling = currentNode.NextSibling; currentNode.Dispose(); currentNode = nextSibling; } } } break; case TraverseDirection.Up: // See if we can find siblings (need to have a parent) if (nodeStack.Count > 1) { var parent = nodeStack.Peek(); using (var lastChild = parent.LastChild) { if (currentNode.IsSame(lastChild)) { // No sibling left, go further up nodeStack.Pop(); currentNode.Dispose(); currentNode = parent; } else { // There's a sibling, try to traverse down again (depth first) traverseDirection = TraverseDirection.Down; var nextSibling = currentNode.NextSibling; currentNode.Dispose(); currentNode = nextSibling; } } } else { // No parent left, we have to be the root -> EOF currentNode.Dispose(); currentNode = null; readState = System.Xml.ReadState.EndOfFile; return(false); } break; } if (currentNode != null) { // See if this node defines a new namespace if (currentNode.IsElement && currentNode.HasAttributes) { attributeMap = currentNode.GetAttributes(); switch (traverseDirection) { case TraverseDirection.Down: foreach (var entry in attributeMap) { var key = entry.Key; var value = entry.Value; if (key.StartsWith("xmlns")) { var prefix = GetLocalName(key); namespaceManager.AddNamespace(prefix, value); break; } } namespaceManager.PushScope(); break; case TraverseDirection.Up: namespaceManager.PopScope(); break; } } else { attributeMap = null; } } return(CheckReadStateAndReturn()); }
public override bool Read() { // First call to Read if (ReadState == System.Xml.ReadState.Initial) { nodeStack.Push(rootNode); currentNode = rootNode.GetFirstChild(); return(CheckReadStateAndReturn()); } if (xmlReader != null) { var result = xmlReader.Read(); if (result && xmlReader.Depth > 0) { return(result); } else { xmlReader.Close(); textReader.Dispose(); xmlReader = null; textReader = null; } } switch (traverseDirection) { case TraverseDirection.Down: // As long as there're children go down (depth first) if (currentNode.HasChildren) { nodeStack.Push(currentNode); currentNode = currentNode.GetFirstChild(); } else { var parent = nodeStack.Peek(); var lastChild = parent.GetLastChild(); if (currentNode.IsSame(lastChild)) { // Time to move back up nodeStack.Pop(); traverseDirection = TraverseDirection.Up; currentNode.Dispose(); currentNode = parent; } else { // There're still siblings left to visit var nextSibling = currentNode.GetNextSibling(); currentNode.Dispose(); currentNode = nextSibling; } // Avoid double disposal GC.SuppressFinalize(lastChild); } break; case TraverseDirection.Up: // See if we can find siblings (need to have a parent) if (nodeStack.Count > 1) { var parent = nodeStack.Peek(); var lastChild = parent.GetLastChild(); if (currentNode.IsSame(lastChild)) { // No sibling left, go further up nodeStack.Pop(); currentNode.Dispose(); currentNode = parent; } else { // There's a sibling, try to traverse down again (depth first) traverseDirection = TraverseDirection.Down; var nextSibling = currentNode.GetNextSibling(); currentNode.Dispose(); currentNode = nextSibling; } // Avoid double disposal GC.SuppressFinalize(lastChild); } else { // No parent left, we have to be the root -> EOF currentNode.Dispose(); currentNode = null; readState = System.Xml.ReadState.EndOfFile; return(false); } break; } if (currentNode != null) { // See if this node defines a new namespace if (currentNode.HasElementAttributes()) { attributeMap = currentNode.GetElementAttributes(); switch (traverseDirection) { case TraverseDirection.Down: for (int i = 0; i < attributeMap.Count; i++) { string key, value; if (attributeMap.TryGetKey(i, out key) && attributeMap.TryGetValue(i, out value)) { if (key.StartsWith("xmlns")) { var prefix = GetPrefix(key); namespaceManager.AddNamespace(prefix, value); } } } namespaceManager.PushScope(); break; case TraverseDirection.Up: namespaceManager.PopScope(); break; } } else { attributeMap = null; } } return(CheckReadStateAndReturn()); }