MoveToNextContent() public abstract method

Reposition the navigator to the next matching content node (inc. attributes); skip over filtered nodes. If there are no matching nodes, then don't move navigator and return false.
public abstract MoveToNextContent ( XPathNavigator navigator ) : bool
navigator System.Xml.XPath.XPathNavigator
return bool
Exemplo n.º 1
0
        /// <summary>
        /// Position this iterator to the next content or sibling node.  Return IteratorResult.NoMoreNodes if there are
        /// no more content or sibling nodes.  Return IteratorResult.NeedInputNode if the next input node needs to be
        /// fetched first.  Return IteratorResult.HaveCurrent if the Current property is set to the next node in the
        /// iteration.
        /// </summary>
        internal IteratorResult MoveNext(XPathNavigator input, bool isContent)
        {
            switch (_state)
            {
            case IteratorState.NeedCurrent:
                // If there are no more input nodes, then iteration is complete
                if (input == null)
                {
                    return(IteratorResult.NoMoreNodes);
                }

                // Save the input node as the current node
                _navCurrent = XmlQueryRuntime.SyncToNavigator(_navCurrent, input);

                // If matching child or sibling is found, then we have a current node
                if (isContent ? _filter.MoveToContent(_navCurrent) :
                    _filter.MoveToFollowingSibling(_navCurrent))
                {
                    _state = IteratorState.HaveCurrentNeedNext;
                }

                return(IteratorResult.NeedInputNode);

            case IteratorState.HaveCurrentNeedNext:
                if (input == null)
                {
                    // There are no more input nodes, so enter HaveCurrentNoNext state and return Current
                    _state = IteratorState.HaveCurrentNoNext;
                    return(IteratorResult.HaveCurrentNode);
                }

                // Save the input node as the next node
                _navNext = XmlQueryRuntime.SyncToNavigator(_navNext, input);

                // If matching child or sibling is found,
                if (isContent ? _filter.MoveToContent(_navNext) :
                    _filter.MoveToFollowingSibling(_navNext))
                {
                    // Then compare position of current and next nodes
                    _state = IteratorState.HaveCurrentHaveNext;
                    return(DocOrderMerge());
                }

                // Input node does not result in matching child or sibling, so get next input node
                return(IteratorResult.NeedInputNode);

            case IteratorState.HaveCurrentNoNext:
            case IteratorState.HaveCurrentHaveNext:
                // If the current node has no more matching siblings,
                if (isContent ? !_filter.MoveToNextContent(_navCurrent) :
                    !_filter.MoveToFollowingSibling(_navCurrent))
                {
                    if (_navStack.IsEmpty)
                    {
                        if (_state == IteratorState.HaveCurrentNoNext)
                        {
                            // No more input nodes, so iteration is complete
                            return(IteratorResult.NoMoreNodes);
                        }

                        // Make navNext the new current node and fetch a new navNext
                        _navCurrent = XmlQueryRuntime.SyncToNavigator(_navCurrent, _navNext);
                        _state      = IteratorState.HaveCurrentNeedNext;
                        return(IteratorResult.NeedInputNode);
                    }

                    // Pop new current node from the stack
                    _navCurrent = _navStack.Pop();
                }

                // If there is no next node, then no need to call DocOrderMerge; just return the current node
                if (_state == IteratorState.HaveCurrentNoNext)
                {
                    return(IteratorResult.HaveCurrentNode);
                }

                // Compare positions of current and next nodes
                return(DocOrderMerge());
            }

            Debug.Assert(false, "Invalid IteratorState " + _state);
            return(IteratorResult.NoMoreNodes);
        }