/// <summary> /// Called by ObjectXPathNavigator when it detects a loop inside object hierarchy /// </summary> /// <param name="e"></param> internal void OnLoopDetected(LoopDetectionEventArgs e) { if (LoopDetected != null) { LoopDetected(this, e); } }
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 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; var 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; continue; } // 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 ) { current = newnode; continue; } } break; } while( true ); if( old != null ) _navigationStack.Push( old ); return newnode; }
private Node GetNonTransparentSibling(Node current, bool goForward) { if (current.NodeType == XPathNodeType.Attribute) { return(null); } Node newnode; var 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; } continue; } // 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) { current = newnode; continue; } } } break; } while(true); if (old != null) { _navigationStack.Push(old); } return(newnode); }