1 package net.sf.saxon.tinytree; 2 import net.sf.saxon.om.AxisIteratorImpl; 3 import net.sf.saxon.om.Item; 4 import net.sf.saxon.om.SequenceIterator; 5 import net.sf.saxon.pattern.NodeTest; 6 import net.sf.saxon.style.StandardNames; 7 import net.sf.saxon.type.Type; 8 9 17 18 final class SiblingEnumeration extends AxisIteratorImpl { 19 20 private TinyTree tree; 21 private int nextNodeNr; 22 private NodeTest test; 23 private TinyNodeImpl startNode; 24 private TinyNodeImpl parentNode; 25 private boolean getChildren; 26 private boolean needToAdvance = false; 27 28 37 38 SiblingEnumeration(TinyTree tree, TinyNodeImpl node, 39 NodeTest nodeTest, boolean getChildren) { 40 this.tree = tree; 41 test = nodeTest; 42 startNode = node; 43 this.getChildren = getChildren; 44 if (getChildren) { parentNode = node; 46 nextNodeNr = node.nodeNr + 1; 49 50 } else { parentNode = (TinyNodeImpl)node.getParent(); 52 if (parentNode == null) { 53 nextNodeNr = -1; 54 } else { 55 nextNodeNr = tree.next[node.nodeNr]; 57 while (tree.nodeKind[nextNodeNr] == Type.PARENT_POINTER) { 58 nextNodeNr = tree.next[nextNodeNr]; 60 } 61 if (nextNodeNr < node.nodeNr) { 62 nextNodeNr = -1; 64 } 65 } 66 } 67 68 if (nextNodeNr >= 0 && nodeTest != null) { 70 if (!nodeTest.matches(this.tree, nextNodeNr)) { 71 needToAdvance = true; 72 } 73 } 74 } 75 76 public Item next() { 77 if (needToAdvance) { 79 final int thisNode = nextNodeNr; 80 if (test==null) { 81 do { 82 nextNodeNr = tree.next[nextNodeNr]; 83 } while (tree.nodeKind[nextNodeNr] == Type.PARENT_POINTER); 84 } else { 85 do { 86 nextNodeNr = tree.next[nextNodeNr]; 87 } while ( nextNodeNr >= thisNode && 88 !test.matches(tree, nextNodeNr)); 89 } 90 91 if (nextNodeNr < thisNode) { nextNodeNr = -1; 93 needToAdvance = false; 94 current = null; 95 position = -1; 96 return null; 97 } 98 } 99 100 if (nextNodeNr == -1) { 101 return null; 102 } 103 needToAdvance = true; 104 position++; 105 106 109 if (isAtomizing() && tree.getTypeAnnotation(nextNodeNr) == StandardNames.XDT_UNTYPED) { 110 current = tree.getUntypedAtomicValue(nextNodeNr); 111 return current; 112 } else { 113 current = tree.getNode(nextNodeNr); 114 ((TinyNodeImpl)current).setParentNode(parentNode); 115 return current; 116 } 117 } 118 119 122 123 public SequenceIterator getAnother() { 124 return new SiblingEnumeration(tree, startNode, test, getChildren); 125 } 126 127 } 128 129 130 | Popular Tags |