private Node GetNonTransparentChild(Node current, bool goForward) { if (current.ChildrenCount == 0) { return(null); } Node newNode; bool inStack = false; int index = goForward ? 0 : current.ChildrenCount - 1; do { newNode = current.GetChild(index); if (newNode == null && current.IsTransparent) { return(GetNonTransparentSibling(current, goForward)); } // If we have to detect loops. if (_context.DetectLoops) { if (newNode != null && newNode.Object != null && _navigationStack.Contains(newNode.Object)) { var evt = new LoopDetectionEventArgs(this, newNode); _context.OnLoopDetected(evt); if (!evt.IgnoreLoop) { inStack = true; Trace(() => String.Format("GetNonTransparentChild {0} already in stack", newNode.Object)); if (goForward) { index++; } else { index--; } continue; } } else { inStack = false; } } current = newNode; if (current != null) { index = goForward ? 0 : current.ChildrenCount - 1; } } while(inStack || (current != null && current.IsTransparent && !IsNodeXPathNavigable(current))); // Break if current is null, or non trasparent or navigable return(current); }
private Node GetNonTransparentSibling(Node current, bool goForward) { if (current.NodeType == XPathNodeType.Attribute) { return(null); } Node newnode = null; Node parent = current.Parent; if (parent == null) { return(null); } Object old = null; if (_context.DetectLoops) { if (_navigationStack.Count > 0) { old = _navigationStack.Pop(); } } do { newnode = goForward ? parent.GetChild(current.Index + 1) : parent.GetChild(current.Index - 1); // While there are no more nodes in this transparent parent, try to // ascend up the hierarchy and take node next to this transparent node. while (newnode == null && parent.IsTransparent) { newnode = parent; parent = parent.Parent; newnode = goForward ? parent.GetChild(newnode.Index + 1) : parent.GetChild(newnode.Index - 1); } // If node is found but it is transparent and not navigable if (newnode != null && newnode.IsTransparent && !IsNodeXPathNavigable(newnode)) { current = newnode; newnode = GetNonTransparentChild(current, goForward); if (newnode != null) { break; } else { continue; } } // If we have to detect loops else if (_context.DetectLoops) { if (newnode != null && newnode.Object != null && _navigationStack.Contains(newnode.Object)) { var evt = new LoopDetectionEventArgs(this, newnode); _context.OnLoopDetected(evt); if (!evt.IgnoreLoop) { current = newnode; continue; } } } break; } while(true); if (old != null) { _navigationStack.Push(old); } return(newnode); }
private Node GetNonTransparentChild(Node current, bool goForward) { if( current.ChildrenCount == 0 ) return null; Node newNode; bool inStack = false; int index = goForward ? 0 : current.ChildrenCount - 1; do { newNode = current.GetChild( index ); if( newNode == null && current.IsTransparent ) return GetNonTransparentSibling( current, goForward ); // If we have to detect loops. if( _context.DetectLoops ) { if( newNode != null && newNode.Object != null && _navigationStack.Contains( newNode.Object ) ) { var evt = new LoopDetectionEventArgs( this, newNode ); _context.OnLoopDetected( evt ); if( !evt.IgnoreLoop ) { inStack = true; Trace( () => String.Format( "GetNonTransparentChild {0} already in stack", newNode.Object ) ); if( goForward ) index++; else index--; continue; } } else inStack = false; } current = newNode; if( current != null ) index = goForward ? 0 : current.ChildrenCount - 1; } while( inStack || ( current != null && current.IsTransparent && !IsNodeXPathNavigable( current ) ) ); // Break if current is null, or non trasparent or navigable return current; }