1 package net.sf.saxon.om; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.value.Whitespace; 4 import net.sf.saxon.value.Value; 5 import net.sf.saxon.style.StandardNames; 6 import net.sf.saxon.event.Receiver; 7 import net.sf.saxon.event.Stripper; 8 import net.sf.saxon.pattern.NodeKindTest; 9 import net.sf.saxon.pattern.NodeTest; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.type.Type; 12 13 14 24 25 public class StrippedNode implements NodeInfo, VirtualNode { 26 27 protected NodeInfo node; 28 protected StrippedNode parent; protected StrippedDocument docWrapper; 30 31 protected StrippedNode() {} 32 33 39 40 protected StrippedNode(NodeInfo node, StrippedNode parent) { 41 this.node = node; 42 this.parent = parent; 43 } 44 45 53 54 protected StrippedNode makeWrapper(NodeInfo node, 55 StrippedDocument docWrapper, 56 StrippedNode parent) { 57 StrippedNode wrapper = new StrippedNode(node, parent); 58 wrapper.docWrapper = docWrapper; 59 return wrapper; 60 } 61 62 65 66 public Object getUnderlyingNode() { 67 return node; 68 } 69 70 73 74 public Configuration getConfiguration() { 75 return node.getConfiguration(); 76 } 77 78 82 83 public NamePool getNamePool() { 84 return node.getNamePool(); 85 } 86 87 91 92 public int getNodeKind() { 93 return node.getNodeKind(); 94 } 95 96 99 100 public SequenceIterator getTypedValue() throws XPathException { 101 return node.getTypedValue(); 102 } 103 104 114 115 public Value atomize() throws XPathException { 116 return node.atomize(); 117 } 118 119 123 124 public int getTypeAnnotation() { 125 return node.getTypeAnnotation(); 126 } 127 128 134 135 public boolean isSameNodeInfo(NodeInfo other) { 136 if (other instanceof StrippedNode) { 137 return node.isSameNodeInfo(((StrippedNode)other).node); 138 } else { 139 return node.isSameNodeInfo(other); 140 } 141 } 142 143 149 150 public String getSystemId() { 151 return node.getSystemId(); 152 } 153 154 public void setSystemId(String uri) { 155 node.setSystemId(uri); 156 } 157 158 163 164 public String getBaseURI() { 165 return node.getBaseURI(); 166 } 167 168 172 173 public int getLineNumber() { 174 return node.getLineNumber(); 175 } 176 177 185 186 public int compareOrder(NodeInfo other) { 187 if (other instanceof StrippedNode) { 188 return node.compareOrder(((StrippedNode)other).node); 189 } else { 190 return node.compareOrder(other); 191 } 192 } 193 194 200 201 public String getStringValue() { 202 return getStringValueCS().toString(); 203 } 204 205 209 210 public CharSequence getStringValueCS() { 211 switch (getNodeKind()) { 213 case Type.DOCUMENT: 214 case Type.ELEMENT: 215 AxisIterator iter = iterateAxis(Axis.DESCENDANT, NodeKindTest.makeNodeKindTest(Type.TEXT)); 216 FastStringBuffer sb = new FastStringBuffer(1024); 217 while(true) { 218 NodeInfo it = (NodeInfo)iter.next(); 219 if (it == null) { 220 break; 221 } 222 sb.append(it.getStringValueCS()); 223 } 224 return sb.condense(); 225 default: 226 return node.getStringValueCS(); 227 } 228 } 229 230 238 239 public int getNameCode() { 240 return node.getNameCode(); 241 } 242 243 249 250 public int getFingerprint() { 251 return node.getFingerprint(); 252 } 253 254 259 260 public String getLocalPart() { 261 return node.getLocalPart(); 262 } 263 264 270 271 public String getURI() { 272 return node.getURI(); 273 } 274 275 281 282 public String getPrefix() { 283 return node.getPrefix(); 284 } 285 286 292 293 public String getDisplayName() { 294 return node.getDisplayName(); 295 } 296 297 300 301 public NodeInfo getParent() { 302 if (parent==null) { 303 NodeInfo realParent = node.getParent(); 304 if (realParent != null) { 305 parent = makeWrapper(realParent, docWrapper, null); 306 } 307 } 308 return parent; 309 } 310 311 316 317 public AxisIterator iterateAxis(byte axisNumber) { 318 switch (axisNumber) { 319 case Axis.ATTRIBUTE: 320 case Axis.NAMESPACE: 321 return new WrappingIterator(node.iterateAxis(axisNumber), this); 322 case Axis.CHILD: 323 return new StrippingIterator(node.iterateAxis(axisNumber), this); 324 case Axis.FOLLOWING_SIBLING: 325 case Axis.PRECEDING_SIBLING: 326 StrippedNode parent = (StrippedNode)getParent(); 327 if (parent == null) { 328 return EmptyIterator.getInstance(); 329 } else { 330 return new StrippingIterator(node.iterateAxis(axisNumber), parent); 331 } 332 default: 333 return new StrippingIterator(node.iterateAxis(axisNumber), null); 334 } 335 } 336 337 343 344 public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) { 345 return new Navigator.AxisFilter(iterateAxis(axisNumber), nodeTest); 346 } 347 348 353 354 public String getAttributeValue(int fingerprint) { 355 return node.getAttributeValue(fingerprint); 356 } 357 358 362 363 public NodeInfo getRoot() { 364 return docWrapper; 365 } 366 367 371 372 public DocumentInfo getDocumentRoot() { 373 return docWrapper; 374 } 375 376 381 382 public boolean hasChildNodes() { 383 return node.hasChildNodes(); 384 } 385 386 393 394 public String generateId() { 395 return node.generateId(); 396 } 397 398 402 403 public int getDocumentNumber() { 404 return docWrapper.getDocumentNumber(); 405 } 406 407 410 411 public void copy(Receiver out, int whichNamespaces, boolean copyAnnotations, int locationId) throws XPathException { 412 Stripper stripper = docWrapper.getStripper().getAnother(); 415 stripper.setUnderlyingReceiver(out); 416 node.copy(stripper, whichNamespaces, copyAnnotations, locationId); 417 } 418 419 425 426 public void sendNamespaceDeclarations(Receiver out, boolean includeAncestors) 427 throws XPathException { 428 node.sendNamespaceDeclarations(out, includeAncestors); 429 } 430 431 446 447 public int[] getDeclaredNamespaces(int[] buffer) { 448 return node.getDeclaredNamespaces(buffer); 449 } 450 451 458 459 private final class WrappingIterator implements AxisIterator, AtomizableIterator { 460 461 AxisIterator base; 462 StrippedNode parent; 463 Item current; 464 boolean atomizing = false; 465 466 472 473 public WrappingIterator(AxisIterator base, StrippedNode parent) { 474 this.base = base; 475 this.parent = parent; 476 } 477 478 public Item next() { 479 Item n = base.next(); 480 if (n instanceof NodeInfo && !atomizing) { 481 current = makeWrapper((NodeInfo)n, docWrapper, parent); 482 } else { 483 current = n; 484 } 485 return current; 486 } 487 488 public Item current() { 489 return current; 490 } 491 492 public int position() { 493 return base.position(); 494 } 495 496 public SequenceIterator getAnother() { 497 return new WrappingIterator((AxisIterator)base.getAnother(), parent); 498 } 499 500 509 510 public int getProperties() { 511 return 0; 512 } 513 514 523 524 public void setIsAtomizing(boolean atomizing) { 525 this.atomizing = true; 526 if (base instanceof AtomizableIterator) { 527 ((AtomizableIterator)base).setIsAtomizing(atomizing); 528 } 529 } 530 531 } 533 540 541 private final class StrippingIterator implements AxisIterator { 542 543 AxisIterator base; 544 StrippedNode parent; 545 NodeInfo currentVirtualNode; 546 int position; 547 548 554 555 public StrippingIterator(AxisIterator base, StrippedNode parent) { 556 this.base = base; 557 this.parent = parent; 558 position = 0; 559 } 560 561 public Item next() { 562 NodeInfo nextRealNode; 563 while (true) { 564 nextRealNode = (NodeInfo)base.next(); 565 if (nextRealNode==null) { 566 return null; 567 } 568 if (isPreserved(nextRealNode)) { 569 break; 570 } 571 } 573 574 currentVirtualNode = makeWrapper(nextRealNode, docWrapper, parent); 575 position++; 576 return currentVirtualNode; 577 } 578 579 private boolean isPreserved(NodeInfo nextRealNode) { 580 if (nextRealNode.getNodeKind() != Type.TEXT) { 581 return true; 582 } 583 if (!Whitespace.isWhite(nextRealNode.getStringValueCS())) { 584 return true; 585 } 586 NodeInfo actualParent = 587 (parent==null ? nextRealNode.getParent() : parent.node); 588 589 if (docWrapper.containsPreserveSpace()) { 590 NodeInfo p = actualParent; 591 while (p.getNodeKind() == Type.ELEMENT) { 594 String val = p.getAttributeValue(StandardNames.XML_SPACE); 595 if (val != null) { 596 if ("preserve".equals(val)) { 597 return true; 598 } else if ("default".equals(val)) { 599 break; 600 } 601 } 602 p = p.getParent(); 603 } 604 } 605 606 if (docWrapper.getStripper().isSpacePreserving(actualParent) == Stripper.ALWAYS_PRESERVE) { 607 return true; 608 } 609 return false; 610 } 611 612 public Item current() { 613 return currentVirtualNode; 614 } 615 616 public int position() { 617 return position; 618 } 619 620 public SequenceIterator getAnother() { 621 return new StrippingIterator((AxisIterator)base.getAnother(), parent); 622 } 623 624 633 634 public int getProperties() { 635 return 0; 636 } 637 638 } 640 641 642 } 643 644 | Popular Tags |