1 package com.icl.saxon.om; 2 3 import com.icl.saxon.pattern.Pattern; 4 import com.icl.saxon.om.Axis; 5 import com.icl.saxon.Context; 6 import com.icl.saxon.expr.XPathException; 7 import com.icl.saxon.pattern.NodeTypeTest; 8 import com.icl.saxon.pattern.AnyNodeTest; 9 import com.icl.saxon.pattern.NameTest; 10 import com.icl.saxon.pattern.NodeTest; 11 import java.util.Vector ; 12 13 14 19 20 21 22 public class Navigator { 23 24 27 28 public static boolean isWhite(String content) { 29 for (int i=0; i<content.length(); i++) { 30 char c = content.charAt(i); 31 if (((int)c) > 32) { 33 return false; 34 } 35 } 36 return true; 37 } 38 39 45 46 public static boolean isAncestor(NodeInfo node, NodeInfo other) { 47 NodeInfo parent = other.getParent(); 48 if (parent==null) return false; 49 if (parent.isSameNode(node)) return true; 50 return isAncestor(node, parent); 51 } 52 53 56 57 public static String getPath(NodeInfo node) { 58 String pre; 59 switch (node.getNodeType()) { 60 case NodeInfo.ROOT: 61 return "/"; 62 case NodeInfo.ELEMENT: 63 pre = getPath(node.getParent()); 64 return (pre.equals("/") ? "" : pre) + 65 "/" + node.getDisplayName() + "[" + getNumberSimple(node) + "]"; 66 case NodeInfo.ATTRIBUTE: 67 return getPath(node.getParent()) + "/@" + node.getDisplayName(); 68 case NodeInfo.TEXT: 69 pre = getPath(node.getParent()); 70 return (pre.equals("/") ? "" : pre) + 71 "/text()[" + getNumberSimple(node) + "]"; 72 case NodeInfo.COMMENT: 73 pre = getPath(node.getParent()); 74 return (pre.equals("/") ? "" : pre) + 75 "/comment()[" + getNumberSimple(node) + "]"; 76 case NodeInfo.PI: 77 pre = getPath(node.getParent()); 78 return (pre.equals("/") ? "" : pre) + 79 "/processing-instruction()[" + getNumberSimple(node) + "]"; 80 case NodeInfo.NAMESPACE: 81 return getPath(node.getParent())+ "/namespace::" + node.getLocalName(); 82 default: 83 return ""; 84 } 85 } 86 87 92 93 public static int getNumberSimple(NodeInfo node, Context context) throws XPathException { 94 95 97 int fingerprint = node.getFingerprint(); 98 NodeTest same; 99 100 if (fingerprint==-1) { 101 same = new NodeTypeTest(node.getNodeType()); 102 } else { 103 same = new NameTest(node); 104 } 105 106 NodeEnumeration preceding = node.getEnumeration(Axis.PRECEDING_SIBLING, same); 107 108 int i=1; 109 while (preceding.hasMoreElements()) { 110 NodeInfo prev = preceding.nextElement(); 111 112 int memo = context.getRememberedNumber(prev); 113 if (memo>0) { 114 memo += i; 115 context.setRememberedNumber(node, memo); 116 return memo; 117 } 118 119 i++; 120 } 121 122 context.setRememberedNumber(node, i); 123 return i; 124 } 125 126 131 132 public static int getNumberSimple(NodeInfo node) { 133 134 try { 135 int fingerprint = node.getFingerprint(); 136 NodeTest same; 137 138 if (fingerprint==-1) { 139 same = new NodeTypeTest(node.getNodeType()); 140 } else { 141 same = new NameTest(node); 142 } 143 144 NodeEnumeration preceding = node.getEnumeration(Axis.PRECEDING_SIBLING, same); 145 146 int i=1; 147 while (preceding.hasMoreElements()) { 148 NodeInfo prev = preceding.nextElement(); 149 i++; 150 } 151 152 return i; 153 } catch (XPathException err) { 154 return 1; 156 } 157 } 158 159 172 173 public static int getNumberSingle(NodeInfo node, Pattern count, 174 Pattern from, Context context) throws XPathException { 175 176 checkNumberable(node); 178 if (count==null && from==null) { 179 return getNumberSimple(node, context); 180 } 181 182 boolean knownToMatch = false; 183 if (count==null) { 184 if (node.getFingerprint()==-1) { count = new NodeTypeTest(node.getNodeType()); 186 } else { 187 count = new NameTest(node); 188 } 189 knownToMatch = true; 190 } 191 192 NodeInfo target = node; 193 while (!(knownToMatch || count.matches(target, context))) { 194 target = target.getParent(); 195 if (target==null) { 196 return 0; 197 } 198 if (from!=null && from.matches(target, context)) { 199 return 0; 200 } 201 } 202 203 205 NodeEnumeration preceding = 206 target.getEnumeration(Axis.PRECEDING_SIBLING, AnyNodeTest.getInstance()); 207 int i = 1; 208 while (preceding.hasMoreElements()) { 209 NodeInfo p = preceding.nextElement(); 210 if (count.matches(p, context)) { 211 i++; 212 } 213 } 214 return i; 215 } 216 217 228 229 public static int getNumberAny(NodeInfo node, Pattern count, 230 Pattern from, Context context) throws XPathException { 231 232 234 int num = 0; 235 if (count==null) { 236 if (node.getFingerprint()==-1) { count = new NodeTypeTest(node.getNodeType()); 238 } else { 239 count = new NameTest(node); 240 } 241 num = 1; 242 } else if (count.matches(node, context)) { 243 num = 1; 244 } 245 246 249 NodeEnumeration preceding = 250 node.getEnumeration(Axis.PRECEDING_OR_ANCESTOR, AnyNodeTest.getInstance()); 251 252 while (preceding.hasMoreElements()) { 253 NodeInfo prev = preceding.nextElement(); 254 if (from!=null && from.matches(prev, context)) { 255 return num; 256 } 257 if (count.matches(prev, context)) { 258 num++; 259 } 260 } 261 return num; 262 } 263 264 276 277 public static Vector getNumberMulti(NodeInfo node, Pattern count, 278 Pattern from, Context context) throws XPathException { 279 280 282 Vector v = new Vector (); 283 284 if (count==null) { 285 if (node.getFingerprint()==-1) { count = new NodeTypeTest(node.getNodeType()); 287 } else { 288 count = new NameTest(node); 289 } 290 } 291 292 NodeInfo curr = node; 293 294 while(true) { 295 if (count.matches(curr, context)) { 296 int num = getNumberSingle(curr, count, null, context); 297 v.insertElementAt(new Integer (num), 0); 298 } 299 curr = curr.getParent(); 300 if (curr==null) break; 301 if (from!=null && from.matches(curr, context)) break; 302 } 303 304 return v; 305 } 306 307 private static void checkNumberable(NodeInfo node) throws XPathException { 308 short type = node.getNodeType(); 309 if (type == NodeInfo.ATTRIBUTE) { 310 throw new XPathException("Attribute nodes cannot be numbered"); 311 } 312 if (type == NodeInfo.NAMESPACE) { 313 throw new XPathException("Namespace nodes cannot be numbered"); 314 } 315 } 316 317 } 318 319 | Popular Tags |