01: package net.sf.saxon.tinytree;
02:
03: import net.sf.saxon.om.AxisIteratorImpl;
04: import net.sf.saxon.om.Item;
05: import net.sf.saxon.om.SequenceIterator;
06: import net.sf.saxon.pattern.NodeTest;
07:
08: /**
09: * Enumerate all the nodes on the preceding axis from a given start node.
10: * The calling code ensures that the start node is not a root, attribute,
11: * or namespace node. As well as the standard XPath preceding axis, this
12: * class also implements a Saxon-specific "preceding-or-ancestor" axis
13: * which returns ancestor nodes as well as preceding nodes. This is used
14: * when performing xsl:number level="any".
15: */
16:
17: final class PrecedingEnumeration extends AxisIteratorImpl {
18:
19: private TinyTree tree;
20: private TinyNodeImpl startNode;
21: private NodeTest test;
22: private int nextAncestorDepth;
23: private boolean includeAncestors;
24:
25: public PrecedingEnumeration(TinyTree doc, TinyNodeImpl node,
26: NodeTest nodeTest, boolean includeAncestors) {
27:
28: this .includeAncestors = includeAncestors;
29: test = nodeTest;
30: tree = doc;
31: startNode = node;
32: current = startNode;
33: nextAncestorDepth = doc.depth[node.nodeNr] - 1;
34: }
35:
36: public Item next() {
37: int nextNodeNr = ((TinyNodeImpl) current).nodeNr;
38: while (true) {
39: nextNodeNr--;
40: if (!includeAncestors) {
41: // skip over ancestor elements
42: while (nextAncestorDepth >= 0
43: && tree.depth[nextNodeNr] == nextAncestorDepth) {
44: if (nextAncestorDepth-- <= 0) { // bug 1121528
45: current = null;
46: position = -1;
47: return null;
48: }
49: ;
50: nextNodeNr--;
51: }
52: } else if (tree.depth[nextNodeNr] == 0) {
53: current = null;
54: position = -1;
55: return null;
56: }
57: if (test.matches(tree, nextNodeNr)) {
58: position++;
59: current = tree.getNode(nextNodeNr);
60: return current;
61: }
62: if (tree.depth[nextNodeNr] == 0) {
63: current = null;
64: position = -1;
65: return null;
66: }
67: }
68: }
69:
70: /**
71: * Get another enumeration of the same nodes
72: */
73:
74: public SequenceIterator getAnother() {
75: return new PrecedingEnumeration(tree, startNode, test,
76: includeAncestors);
77: }
78: }
79:
80: //
81: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
82: // you may not use this file except in compliance with the License. You may obtain a copy of the
83: // License at http://www.mozilla.org/MPL/
84: //
85: // Software distributed under the License is distributed on an "AS IS" basis,
86: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
87: // See the License for the specific language governing rights and limitations under the License.
88: //
89: // The Original Code is: all this file.
90: //
91: // The Initial Developer of the Original Code is Michael H. Kay.
92: //
93: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
94: //
95: // Contributor(s): none.
96: //
|