コード例 #1
0
		internal ObjectXPathNavigator(object obj, ObjectXPathContext context)
		{

			_context = context;

			_root = new Node(_context, new RootNodePolicy(obj));
			_node = _root;

			if (_context.DetectLoops)
			{
				_navigationStack = new Stack();
				_navigationStack.Push( _root ); // Push dummy root object
				//_navigationStack.Push(_node.Object);

				//Trace( String.Format( "Ctor1: Pushedg {0} {1}", _node.Object, StackList ) );
			}

			_lang = _context.NameTable.Add("");
		}
コード例 #2
0
ファイル: Node.cs プロジェクト: zanyants/mvp.xml
		/*
		protected int Depth
		{
			get
			{
				if (_parent == null)
					return 0;
				else
					return _parent.Depth + 1;
			}
		}
		protected bool ContainedBelow( Node node )
		{
			if (node.Object == this.Object || Depth > 7  )
				return true;

			
			if (_parent == null)
				return false;

			return _parent.ContainedBelow( node );

		}*/

		/// <summary>
		/// Adds the child to this node.
		/// </summary>
		/// <param name="child">Child node to add.</param>
		/// <remarks>This method should be used with caution, because it could
		/// cause interference with child nodes returned by the node policy.</remarks>
		public void AddChild( Node child )
		{
			int index = ChildrenCount;
			CacheChild( index, child );
			child.Parent = this;
			child.Index = index;
			_elementsCount = ChildrenCount + 1;
		}
コード例 #3
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToRoot" /> for details.
		/// </summary>
		public override void MoveToRoot()
		{
#if DEBUG
			Trace("MoveToRoot");
#endif
			_node = _root;
			_childNav = null;

			if (_context.DetectLoops)
			{
				_navigationStack.Clear();
				Trace( () => String.Format("Move2Root {0} {1}", _node.Object, GetNavigationStack()));
				//_navigationStack.Push(_root.Object);
		}
		}
コード例 #4
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToParent" /> for details.
		/// </summary>
		public override bool MoveToParent()
		{
#if DEBUG
			Trace("MoveToParent");
			Trace( GetNavigationStack );
			//System.Diagnostics.StackTrace st = new StackTrace();
			//Trace( st.ToString()  );
#endif

			// Invoke child navigator
			if (_childNav != null)
			{
				Trace(() => String.Format("Trace: ChildNav"));
				if (_childNavDepth == 0)
				{
					// We reached root node of the child navigator
					_childNav = null;
					if (!_node.IsTransparent)
						// Child navigator cleared, we are at its non-transparent container
						return true;
				}
				else
				{
					// Descend one level
					_childNav.MoveToParent();
					_childNavDepth--;
					return true;
				}
			}

			Node parent = GetNonTransparentParent(_node);

			if (_context.DetectLoops)
				if (parent != null)
			{
					Trace( () => String.Format("Move2Parent popping {0}", GetNavigationStack()));
					if (_navigationStack.Count > 0)
						_navigationStack.Pop();
					else
					{
						Trace(() => String.Format( "MoveToParent: Stack is empty") );
					}
				}

			if (parent != null)
			{
				_node = parent;
				return true;
			}

			return false;
		}
コード例 #5
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToNextAttribute" /> for details.
		/// </summary>
		public override bool MoveToNextAttribute()
		{
#if DEBUG
			Trace("MoveToNextAttribute");
#endif

			// Invoke child navigator
			if (_childNav != null)
				return _childNav.MoveToNextAttribute();

			if (_node.NodeType != XPathNodeType.Attribute)
				return false;

			for (int i = _node.Index + 1; i < _node.Parent.AttributesCount; i++)
			{
				Node newnode = _node.Parent.GetAttribute(i);
				if (newnode != null && !newnode.IsTransparent)
				{
					_node = newnode;
					if (_context.DetectLoops)
					{
						Trace( () => String.Format("Move2NextAttr popping {0}", GetNavigationStack()));
						if (_navigationStack.Count > 0)
							_navigationStack.Pop();
						else
							Trace(() => String.Format("MoveToNextAttribute: Stack is empty {0}", GetNavigationStack()));

						_navigationStack.Push(newnode.Object);

						//Trace(String.Format("~Move2NextAttr Pushed {0} {1}", _node.Object, StackList));
					}

					return true;
				}
			}
			Trace(() => String.Format("~Move2NextAttr"));
			return false;
		}
コード例 #6
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToPrevious" /> for details.
		/// </summary>
		public override bool MoveToPrevious()
		{
#if DEBUG
			Trace("MoveToPrevious");
#endif

			// Invoke child navigator
			if (_childNav != null)
			{
				bool res = _childNav.MoveToPrevious();
				if (res)
					return true;
				if (!_node.IsTransparent || _childNavDepth > 0)
					return false;
			}


			Node newnode = GetNonTransparentSibling(_node, false);
			while (newnode != null)
			{
				if (!newnode.IsTransparent)
				{
					_node = newnode;
					_childNav = null;

					if (_context.DetectLoops)
					{
						Trace( () => String.Format("Move2Prev Pushing {0} {1}", _node.Object, GetNavigationStack()));
						if (_navigationStack.Count > 0)
							_navigationStack.Pop();
						else
						{
							Trace( () => String.Format("{0} MoveToPrevious : stack empty", Object));
						}
						_navigationStack.Push(newnode.Object);
					}
					return true;
				}
				else
				{
					// It's transparent but navigable node.
					// Try to move into this navigable node.
					if (MoveIntoNavigableNode(newnode))
					{
						_node = newnode;
						// Go to the last sibling of the child navigator's node
						while (_childNav.MoveToNext()) ;

						if (_context.DetectLoops)
						{
							Trace( () => String.Format("Move2Prev {0} {1}", _node.Object, GetNavigationStack()));
							if (_navigationStack.Count > 0)
								_navigationStack.Pop();
							else
							{
								Trace( () => String.Format("{0} MoveToPrevious : stack is empty", Object));
							}
							_navigationStack.Push(newnode.Object);
						}
						return true;
					}
					// If failure, get its sibling
					newnode = GetNonTransparentSibling(newnode, false);
					continue;
				}
			}
			return false;
		}
コード例 #7
0
		private static Node GetNonTransparentParent(Node node)
		{
			Node parent = node.Parent;
			while (parent != null && parent.IsTransparent)
			{
				parent = parent.Parent;
			}
			return parent;
		}
コード例 #8
0
ファイル: Node.cs プロジェクト: zanyants/mvp.xml
		/// <summary>
		/// Caches attribute.
		/// </summary>
		/// <param name="i">Zero-based index of attribute.</param>
		/// <param name="child">Attribute to add..</param>
		private void CacheAttribute( int i, Node child )
		{
			CheckCache( 0 );
			_cache[i] = ( child != null ? child : NullCacheEntry );
		}
コード例 #9
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToFirstAttribute" /> for details.
		/// </summary>
		public override bool MoveToFirstAttribute()
		{
#if DEBUG
			Trace("MoveToFirstAttribute");
#endif

			// Invoke child navigator
			if (_childNav != null)
			{
				bool res = _childNav.MoveToFirstAttribute();
				if (res)
					_childNavDepth++;
				return res;
			}

			if (_node.AttributesCount == 0)
				return false;

			for (int i = 0; i < _node.AttributesCount; i++)
			{
				Node newnode = _node.GetAttribute(i);
				if (newnode != null && !newnode.IsTransparent)
				{
					_node = newnode;
					if (_context.DetectLoops)
					{
						_navigationStack.Push(_node.Object);
						Trace( () => String.Format("Move2.1stAttr Pushed {0} {1}", _node.Object, GetNavigationStack()));
					}
					return true;
				}
			}
			return false;
		}
コード例 #10
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToAttribute" /> for details.
		/// </summary>
		public override bool MoveToAttribute(string localName, string namespaceURI)
		{
#if DEBUG
			Trace("MoveToAttribute");
#endif

			// Invoke child navigator
			if (_childNav != null)
			{
				bool res = _childNav.MoveToAttribute(localName, namespaceURI);
				if (res)
					_childNavDepth++;
				return res;
				// TODO: Check what will happen if we are positioned at the navigable root of the transparent node. 
			}

			if (_node.NodeType != XPathNodeType.Element)
				return false;

			int i = _node.FindAttribute(localName, namespaceURI);
			if (i >= 0)
			{
				Node newnode = _node.GetAttribute(i);
				if (newnode != null && !newnode.IsTransparent)
				{
					_node = newnode;
					return true;
				}
			}
			return false;
		}
コード例 #11
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveTo" /> for details.
		/// </summary>
		public override bool MoveTo(XPathNavigator other)
		{

			var otherNav = other as ObjectXPathNavigator;
			if( otherNav == null )
			{
				return false;
			}

			_context = otherNav._context;
			_root = otherNav._root;
			_node = otherNav._node;
			if( otherNav._childNav != null )
			{
				_childNav = otherNav._childNav.Clone();
				_childNavDepth = otherNav._childNavDepth;
			}
			else
				_childNav = null;

#if DEBUG
			Trace( () => string.Format( "MoveTo( N#{0} )", other.GetHashCode() ) );
#endif

			if( _context.DetectLoops )
			{
				_navigationStack = (Stack) otherNav._navigationStack.Clone();
			}

			return true;
		}
コード例 #12
0
		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;
		}
コード例 #13
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;
		}
コード例 #14
0
ファイル: Node.cs プロジェクト: zanyants/mvp.xml
		private void CheckCache( int elemIndex )
		{
			int elCount = ChildrenCount;
			if( _cache == null ) 
			{
				int size = AttributesCount;
				if( elCount == int.MaxValue || elCount <= elemIndex ) 
				{
					if( elemIndex >= MinimalElementsCacheSize )
						size += elemIndex + 1;
					else
						// Initial elements cache size for unknown number of children
						size += MinimalElementsCacheSize; 
				}
				else
					size += elCount;

				if( size != 0 )
					_cache = new Node[ size ]; 
				else
					_cache = EmptyCache;
			} 
			else if( elCount == int.MaxValue || elCount <= elemIndex ) 
			{
				// Check if cache has to be expanded
				int size = _cache.Length;
				int elemSize = size - AttributesCount;
				if( elemIndex >= elemSize )
				{
					Node[] newCache = new Node[size + elemSize];
					Array.Copy( _cache, 0, newCache, 0, size );
				}
			}
		}
コード例 #15
0
		/// <summary>
		/// See <see cref="System.Xml.XPath.XPathNavigator.MoveToFirstChild" /> for details.
		/// </summary>
		public override bool MoveToFirstChild()
		{
#if DEBUG
			Trace("MoveToFirstChild");
#endif

			// Invoke child navigator
			if (_childNav != null)
			{
				bool res = _childNav.MoveToFirstChild();
				if (res)
					_childNavDepth++;
				return res;
			}

			// Check if we are trying to descend into IXPathNavigable object
			if (IsNodeXPathNavigable(_node))
			{
				if (MoveIntoNavigableNode(_node))
					return true;
				else
					return false;
			}

			Node newnode = GetNonTransparentChild(_node, true);

			while (newnode != null)
			{	
				if (!newnode.IsTransparent)
			{
					_node = newnode;
					if (_context.DetectLoops)
				{
						Trace( () => String.Format("MoveTo1stChild Pushing {0} {1} TRUE", _node.Object, GetNavigationStack()));
						_navigationStack.Push(newnode.Object);
					}
					return true;
				}
				else
				{
					// It's transparent but navigable node.
					// Try to move into this navigable node.
					if (MoveIntoNavigableNode(newnode))
					{
						_node = newnode;
						if (_context.DetectLoops)
						{
							Trace( () => String.Format("T: MoveTo1stChild Pushing {0} {1} TRUE", _node.Object, GetNavigationStack()));
							_navigationStack.Push(newnode.Object);
						}
						return true;
					}
					// If failure, get its sibling
					newnode = GetNonTransparentSibling(newnode, true);
					continue;
				}
			}
			return false;
		}
コード例 #16
0
ファイル: Node.cs プロジェクト: zanyants/mvp.xml
		/// <summary>
		/// Caches child element.
		/// </summary>
		/// <param name="i">Zero-based index of child element.</param>
		/// <param name="child">Child element to add.</param>
		private void CacheChild( int i, Node child )
		{
			CheckCache( i );
			_cache[AttributesCount + i] = ( child != null ? child : NullCacheEntry );
		}
コード例 #17
0
		private bool MoveIntoNavigableNode(Node node)
		{
			IXPathNavigable navigable = node.Object as IXPathNavigable;
			if (navigable != null)
			{
				_childNav = navigable.CreateNavigator();
				_childNavDepth = 0;
				if (_childNav.NodeType == XPathNodeType.Root
					|| (node.Member != null && node.Member.SkipNavigableRoot != null))
				{
					bool res = _childNav.MoveToFirstChild();
					if (!res)
					{
						// The type of node is Root and we can't descend to a child
						_childNav = null;
						return false;
					}
					_childNav.MoveToFirst();
				}

				// Descended succesfully
				return true;
			}
			return false;
		}
コード例 #18
0
		/// <summary>
		/// Creates a new <see cref="LoopDetectionEventArgs"/> instance.
		/// </summary>
		/// <param name="navigator"><see cref="ObjectXPathNavigator"/> Navigator object</param>
		/// <param name="node"><see cref="Node"/> Node that caused loop appearance</param>
		public LoopDetectionEventArgs( ObjectXPathNavigator navigator, Node node )
		{
			_navigator = navigator;
			_node = node;
			_ignoreLoop = false;
		}
コード例 #19
0
		private static bool IsNodeXPathNavigable(Node node)
		{
			if (node.ObjectType == null)
				return false;
			else
				return node.ObjectType.IsXPathNavigable;
		}