1 package net.sf.saxon.tinytree; 2 import net.sf.saxon.event.Receiver; 3 import net.sf.saxon.om.NamespaceConstant; 4 import net.sf.saxon.om.NamespaceResolver; 5 import net.sf.saxon.om.Navigator; 6 import net.sf.saxon.om.NodeInfo; 7 import net.sf.saxon.style.StandardNames; 8 import net.sf.saxon.trans.XPathException; 9 import net.sf.saxon.type.Type; 10 11 12 19 20 final class TinyElementImpl extends TinyParentNodeImpl { 21 22 25 26 public TinyElementImpl(TinyTree tree, int nodeNr) { 27 this.tree = tree; 28 this.nodeNr = nodeNr; 29 } 30 31 35 36 public final int getNodeKind() { 37 return Type.ELEMENT; 38 } 39 40 44 45 public String getBaseURI() { 46 return Navigator.getBaseURI(this); 47 } 48 49 53 54 public int getTypeAnnotation() { 55 return tree.getTypeAnnotation(nodeNr); 56 } 57 58 63 64 public void sendNamespaceDeclarations(Receiver out, boolean includeAncestors) 65 throws XPathException { 66 67 if (!tree.usesNamespaces) { 68 return; 69 } 70 71 int ns = tree.beta[nodeNr]; if (ns>0 ) { 73 while (ns < tree.numberOfNamespaces && 74 tree.namespaceParent[ns] == nodeNr ) { 75 int nscode = tree.namespaceCode[ns]; 76 out.namespace(nscode, 0); 77 ns++; 78 } 79 } 80 81 84 if (includeAncestors) { 85 NodeInfo parent = getParent(); 86 if (parent != null) { 87 parent.sendNamespaceDeclarations(out, true); 88 } 89 } 91 } 92 93 108 109 public int[] getDeclaredNamespaces(int[] buffer) { 110 return getDeclaredNamespaces(tree, nodeNr, buffer); 111 } 112 113 130 131 static final int[] getDeclaredNamespaces(TinyTree tree, int nodeNr, int[] buffer) { 132 int ns = tree.beta[nodeNr]; if (ns>0 ) { 134 int count = 0; 135 while (ns < tree.numberOfNamespaces && 136 tree.namespaceParent[ns] == nodeNr ) { 137 count++; 138 ns++; 139 } 140 if (count == 0) { 141 return NodeInfo.EMPTY_NAMESPACE_LIST; 142 } else if (count <= buffer.length) { 143 System.arraycopy(tree.namespaceCode, tree.beta[nodeNr], buffer, 0, count); 144 if (count < buffer.length) { 145 buffer[count] = -1; 146 } 147 return buffer; 148 } else { 149 int[] array = new int[count]; 150 System.arraycopy(tree.namespaceCode, tree.beta[nodeNr], array, 0, count); 151 return array; 152 } 153 } else { 154 return NodeInfo.EMPTY_NAMESPACE_LIST; 155 } 156 } 157 158 171 172 static final int[] getInScopeNamespaces(TinyTree tree, int nodeNr, int[] buffer) { 173 174 if (buffer == null || buffer.length == 0) { 175 buffer = new int[10]; 176 } 177 buffer[0] = NamespaceConstant.XML_NAMESPACE_CODE; 178 int used = 1; 179 180 if (tree.usesNamespaces) { 181 do { 182 int ns = tree.beta[nodeNr]; if (ns>0 ) { 185 while (ns < tree.numberOfNamespaces && 186 tree.namespaceParent[ns] == nodeNr ) { 187 int nscode = tree.namespaceCode[ns]; 188 189 short prefixCode = (short)(nscode >> 16); 191 boolean duplicate = false; 192 for (int i=0; i<used; i++) { 193 if ((buffer[i] >> 16) == prefixCode) { 194 duplicate = true; 195 break; 196 } 197 } 198 if (!duplicate) { 199 if (used >= buffer.length) { 200 int[] b2 = new int[used*2]; 201 System.arraycopy(buffer, 0, b2, 0, used); 202 buffer = b2; 203 } 204 buffer[used++] = nscode; 205 } 206 ns++; 207 } 208 } 209 210 nodeNr = getParentNodeNr(tree, nodeNr); 212 } while (nodeNr != -1); 213 214 217 int j = 0; 218 for (int i=0; i<used; i++) { 219 int nscode = buffer[i]; 220 if ((nscode & 0xffff) != 0) { 221 buffer[j++] = nscode; 222 } 223 } 224 used = j; 225 } 226 227 if (used < buffer.length) { 229 buffer[used] = -1; 230 } 231 232 return buffer; 233 } 234 235 236 241 242 public String getAttributeValue(int fingerprint) { 243 int a = tree.alpha[nodeNr]; 244 if (a<0) return null; 245 while (a < tree.numberOfAttributes && tree.attParent[a] == nodeNr) { 246 if ((tree.attCode[a] & 0xfffff) == fingerprint ) { 247 return tree.attValue[a].toString(); 248 } 249 a++; 250 } 251 return null; 252 } 253 254 259 260 public void copy(Receiver receiver, int whichNamespaces, boolean copyAnnotations, int locationId) throws XPathException { 261 262 264 267 short level = -1; 269 boolean closePending = false; 270 short startLevel = tree.depth[nodeNr]; 271 boolean first = true; 272 int next = nodeNr; 273 274 276 do { 277 278 short nodeLevel = tree.depth[next]; 280 281 if (closePending) { 283 level++; 284 } 285 286 for (; level > nodeLevel; level--) { 288 receiver.endElement(); 289 } 290 291 level = nodeLevel; 293 294 switch (tree.nodeKind[next]) { 296 case Type.ELEMENT : { 297 298 receiver.startElement(tree.nameCode[next], 300 (copyAnnotations ? tree.getTypeAnnotation(next): StandardNames.XDT_UNTYPED), 301 locationId, 0); 302 304 closePending = true; 306 307 if (whichNamespaces != NO_NAMESPACES && tree.usesNamespaces) { 309 if (first) { 310 sendNamespaceDeclarations(receiver, whichNamespaces==ALL_NAMESPACES); 311 } else { 312 int ns = tree.beta[next]; if (ns>0 ) { 314 while (ns < tree.numberOfNamespaces && 315 tree.namespaceParent[ns] == next ) { 316 int nscode = tree.namespaceCode[ns]; 317 receiver.namespace(nscode, 0); 318 ns++; 319 } 320 } 321 } 322 } 323 first = false; 324 325 327 int att = tree.alpha[next]; 328 if (att >= 0) { 329 while (att < tree.numberOfAttributes && tree.attParent[att] == next ) { 330 int attCode = tree.attCode[att]; 331 int attType = (copyAnnotations ? tree.getAttributeAnnotation(att) : -1); 332 receiver.attribute(attCode, attType, tree.attValue[att], locationId, 0); 333 att++; 334 } 335 } 336 337 receiver.startContent(); 339 break; 340 } 341 case Type.TEXT : { 342 343 closePending = false; 345 346 int start = tree.alpha[next]; 348 int len = tree.beta[next]; 349 receiver.characters(new CharSlice(tree.charBuffer, start, len), locationId, 0); 350 break; 351 } 352 case Type.COMMENT : { 353 354 closePending = false; 356 357 int start = tree.alpha[next]; 359 int len = tree.beta[next]; 360 if (len>0) { 361 receiver.comment(tree.commentBuffer.subSequence(start, start+len), locationId, 0); 362 } else { 363 receiver.comment("", 0, 0); 364 } 365 break; 366 } 367 case Type.PROCESSING_INSTRUCTION : { 368 369 closePending = false; 371 372 NodeInfo pi = tree.getNode(next); 374 receiver.processingInstruction(pi.getLocalPart(), pi.getStringValue(), locationId, 0); 375 break; 376 } 377 378 case Type.PARENT_POINTER : { 379 closePending = false; 380 } 381 } 382 383 next++; 384 385 } while (next < tree.numberOfNodes && tree.depth[next] > startLevel); 386 387 if (closePending) { 389 level++; 390 } 391 for (; level > startLevel; level--) { 392 receiver.endElement(); 393 } 394 } 395 396 432 433 434 446 447 public String getURIForPrefix(String prefix, boolean useDefault) { 448 if (!useDefault && "".equals(prefix)) { 449 return ""; 450 } 451 int prefixCode = getNamePool().getCodeForPrefix(prefix); 452 if (prefixCode == -1) { 453 return null; 454 } 455 int ns = tree.beta[nodeNr]; if (ns>0 ) { 457 while (ns < tree.numberOfNamespaces && 458 tree.namespaceParent[ns] == nodeNr ) { 459 int nscode = tree.namespaceCode[ns]; 460 if ((nscode >> 16) == prefixCode) { 461 int uriCode = nscode & 0xffff; 462 if (uriCode == 0) { 463 if (prefixCode == 0) { 465 return ""; 467 } else { 468 return null; 469 } 470 } else { 471 return getNamePool().getURIFromURICode((short)uriCode); 472 } 473 } 474 ns++; 475 } 476 } 477 478 480 NodeInfo parent = getParent(); 481 if (parent instanceof NamespaceResolver) { 482 return ((NamespaceResolver)parent).getURIForPrefix(prefix, useDefault); 483 } 484 return null; 485 } 486 487 } 488 489 | Popular Tags |