File: SiblingIterators.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (184 lines) | stat: -rw-r--r-- 7,245 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//------------------------------------------------------------------------------
// <copyright file="SiblingIterators.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Schema;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;

namespace System.Xml.Xsl.Runtime {

    /// <summary>
    /// Iterate over all following-sibling content nodes.
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct FollowingSiblingIterator {
        private XmlNavigatorFilter filter;
        private XPathNavigator navCurrent;

        /// <summary>
        /// Initialize the FollowingSiblingIterator.
        /// </summary>
        public void Create(XPathNavigator context, XmlNavigatorFilter filter) {
            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, context);
            this.filter = filter;
        }

        /// <summary>
        /// Position the iterator on the next following-sibling node.  Return true if such a node exists and
        /// set Current property.  Otherwise, return false (Current property is undefined).
        /// </summary>
        public bool MoveNext() {
            return this.filter.MoveToFollowingSibling(this.navCurrent);
        }

        /// <summary>
        /// Return the current result navigator.  This is only defined after MoveNext() has returned true.
        /// </summary>
        public XPathNavigator Current {
            get { return this.navCurrent; }
        }
    }


    /// <summary>
    /// Iterate over child following-sibling nodes.  This is a simple variation on the ContentMergeIterator, so use containment
    /// to reuse its code (can't use inheritance with structures).
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct FollowingSiblingMergeIterator {
        private ContentMergeIterator wrapped;

        /// <summary>
        /// Initialize the FollowingSiblingMergeIterator.
        /// </summary>
        public void Create(XmlNavigatorFilter filter) {
            this.wrapped.Create(filter);
        }

        /// <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>
        public IteratorResult MoveNext(XPathNavigator navigator) {
            return this.wrapped.MoveNext(navigator, false);
        }

        /// <summary>
        /// Return the current result navigator.  This is only defined after MoveNext() has returned IteratorResult.HaveCurrent.
        /// </summary>
        public XPathNavigator Current {
            get { return this.wrapped.Current; }
        }
    }


    /// <summary>
    /// Iterate over all preceding nodes according to XPath preceding axis rules, returning nodes in reverse
    /// document order.
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct PrecedingSiblingIterator {
        private XmlNavigatorFilter filter;
        private XPathNavigator navCurrent;

        /// <summary>
        /// Initialize the PrecedingSiblingIterator.
        /// </summary>
        public void Create(XPathNavigator context, XmlNavigatorFilter filter) {
            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, context);
            this.filter = filter;
        }

        /// <summary>
        /// Return true if the Current property is set to the next Preceding node in reverse document order.
        /// </summary>
        public bool MoveNext() {
            return this.filter.MoveToPreviousSibling(this.navCurrent);
        }

        /// <summary>
        /// Return the current result navigator.  This is only defined after MoveNext() has returned true.
        /// </summary>
        public XPathNavigator Current {
            get { return this.navCurrent; }
        }
    }


    /// <summary>
    /// Iterate over all preceding-sibling content nodes in document order.
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public struct PrecedingSiblingDocOrderIterator {
        private XmlNavigatorFilter filter;
        private XPathNavigator navCurrent, navEnd;
        private bool needFirst, useCompPos;

        /// <summary>
        /// Initialize the PrecedingSiblingDocOrderIterator.
        /// </summary>
        public void Create(XPathNavigator context, XmlNavigatorFilter filter) {
            this.filter = filter;
            this.navCurrent = XmlQueryRuntime.SyncToNavigator(this.navCurrent, context);
            this.navEnd = XmlQueryRuntime.SyncToNavigator(this.navEnd, context);
            this.needFirst = true;

            // If the context node will be filtered out, then use ComparePosition to
            // determine when the context node has been passed by.  Otherwise, IsSamePosition
            // is sufficient to determine when the context node has been reached.
            this.useCompPos = this.filter.IsFiltered(context);
        }

        /// <summary>
        /// Position the iterator on the next preceding-sibling node.  Return true if such a node exists and
        /// set Current property.  Otherwise, return false (Current property is undefined).
        /// </summary>
        public bool MoveNext() {
            if (this.needFirst) {
                // Get first matching preceding-sibling node
                if (!this.navCurrent.MoveToParent())
                    return false;

                if (!this.filter.MoveToContent(this.navCurrent))
                    return false;

                this.needFirst = false;
            }
            else {
                // Get next matching preceding-sibling node
                if (!this.filter.MoveToFollowingSibling(this.navCurrent))
                    return false;
            }

            // Accept matching sibling only if it precedes navEnd in document order
            if (this.useCompPos)
                return (this.navCurrent.ComparePosition(this.navEnd) == XmlNodeOrder.Before);

            if (this.navCurrent.IsSamePosition(this.navEnd)) {
                // Found the original context node, so iteration is complete.  If MoveNext
                // is called again, use ComparePosition so that false will continue to be
                // returned.
                this.useCompPos = true;
                return false;
            }

            return true;
        }

        /// <summary>
        /// Return the current result navigator.  This is only defined after MoveNext() has returned true.
        /// </summary>
        public XPathNavigator Current {
            get { return this.navCurrent; }
        }
    }
}