示例#1
0
 /// <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);
     }
 }
示例#2
0
        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;
        }
示例#5
0
        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);
        }