1 28 29 package com.caucho.xpath.pattern; 30 31 import com.caucho.xml.XmlUtil; 32 import com.caucho.xpath.Env; 33 import com.caucho.xpath.ExprEnvironment; 34 import com.caucho.xpath.XPathException; 35 36 import org.w3c.dom.Node ; 37 38 41 public class FromDescendants extends Axis { 42 private boolean _self; 43 44 public FromDescendants(AbstractPattern parent, boolean self) 45 { 46 super(parent); 47 48 _self = self; 49 50 if (parent == null) 51 throw new RuntimeException (); 52 } 53 54 63 public boolean match(Node node, ExprEnvironment env) 64 throws XPathException 65 { 66 if (node == null) 67 return false; 68 69 if (! _self) 70 node = node.getParentNode(); 71 72 for (; node != null; node = node.getParentNode()) { 73 if (_parent.match(node, env)) 74 return true; 75 } 76 77 return false; 78 } 79 80 89 public int position(Node node, Env env, AbstractPattern pattern) 90 throws XPathException 91 { 92 int index = env.getPositionIndex(); 93 94 int pos = 0; 95 96 Node parentNode = node; 97 Node ptr = node; 98 99 for (; index >= 0; index--) { 100 for (; parentNode != null; parentNode = parentNode.getParentNode()) { 101 if (_parent.match(parentNode, env)) 102 break; 103 } 104 105 for (; ptr != null; ptr = XmlUtil.getPrevious(ptr)) { 106 if (ptr == parentNode && ! _self) 107 break; 108 109 if (pattern.match(ptr, env)) 110 pos++; 111 112 if (ptr == parentNode) 113 break; 114 } 115 116 if (index > 0 && parentNode != null) { 117 parentNode = parentNode.getParentNode(); 118 if (_self) 119 ptr = XmlUtil.getPrevious(ptr); 120 } 121 else 122 break; 123 } 124 125 if (parentNode != null) 126 parentNode = parentNode.getParentNode(); 127 128 for (; parentNode != null; parentNode = parentNode.getParentNode()) { 129 if (_parent.match(parentNode, env)) { 130 env.setMorePositions(true); 131 break; 132 } 133 } 134 135 return pos; 136 } 137 138 147 public int count(Node node, Env env, AbstractPattern pattern) 148 throws XPathException 149 { 150 int index = env.getPositionIndex(); 151 152 Node axis; 153 if (_self) 154 axis = getAxisContext(node, env); 155 else 156 axis = getAxisContext(node.getParentNode(), env); 157 158 for (; index > 0; index--) 159 axis = getAxisContext(axis.getParentNode(), env); 160 161 if (getAxisContext(axis.getParentNode(), env) != null) 162 env.setMorePositions(true); 163 164 int count = 0; 165 for (Node ptr = axis; 166 ptr != null; 167 ptr = XmlUtil.getNext(ptr)) { 168 if (pattern.match(ptr, env)) 169 count++; 170 } 171 172 return count; 173 } 174 175 178 private Node getAxisContext(Node node, ExprEnvironment env) 179 throws XPathException 180 { 181 for (; node != null; node = node.getParentNode()) { 182 if (_parent.match(node, env)) 183 return node; 184 } 185 186 return node; 187 } 188 189 192 public boolean isStrictlyAscending() 193 { 194 if (_parent == null) 195 return true; 196 else 197 return _parent.isSingleLevel(); 198 } 199 200 207 public Node firstNode(Node node, ExprEnvironment env) 208 { 209 if (_self) 210 return node; 211 else 212 return node.getFirstChild(); 213 } 214 215 223 public Node nextNode(Node node, Node lastNode) 224 { 225 Node next = XmlUtil.getNext(node); 226 227 return next == lastNode ? null : next; 228 } 229 230 237 public Node lastNode(Node node) 238 { 239 Node last = node; 240 241 for (; 242 last != null && last.getNextSibling() == null; 243 last = last.getParentNode()) { 244 } 245 246 return last != null ? last.getNextSibling() : null; 247 } 248 249 public String toString() 250 { 251 if (_self) 252 return getPrefix() + "descendant-or-self::"; 253 else 254 return getPrefix() + "descendant::"; 255 } 256 } 257 | Popular Tags |