1 package net.sf.saxon.xom; 2 3 import net.sf.saxon.Configuration; 4 import net.sf.saxon.trans.XPathException; 5 import net.sf.saxon.event.Receiver; 6 import net.sf.saxon.om.*; 7 import net.sf.saxon.pattern.AnyNodeTest; 8 import net.sf.saxon.pattern.NameTest; 9 import net.sf.saxon.pattern.NodeKindTest; 10 import net.sf.saxon.pattern.NodeTest; 11 import net.sf.saxon.type.Type; 12 import net.sf.saxon.value.UntypedAtomicValue; 13 import net.sf.saxon.value.Value; 14 import nu.xom.*; 15 16 26 27 public class NodeWrapper implements NodeInfo, VirtualNode, SiblingCountingNode { 28 29 protected Node node; 30 31 protected short nodeKind; 32 33 private NodeWrapper parent; 35 protected DocumentWrapper docWrapper; 36 37 protected int index; 39 50 protected NodeWrapper(Node node, NodeWrapper parent, int index) { 51 this.node = node; 52 this.parent = parent; 53 this.index = index; 54 } 55 56 66 protected final NodeWrapper makeWrapper(Node node, DocumentWrapper docWrapper) { 67 return makeWrapper(node, docWrapper, null, -1); 68 } 69 70 84 85 protected final NodeWrapper makeWrapper(Node node, DocumentWrapper docWrapper, 86 NodeWrapper parent, int index) { 87 88 short kind; 89 if (node instanceof Element) { 90 kind = Type.ELEMENT; 91 } else if (node instanceof Attribute) { 92 kind = Type.ATTRIBUTE; 93 } else if (node instanceof Text) { 94 kind = Type.TEXT; 95 } else if (node instanceof Comment) { 96 kind = Type.COMMENT; 97 } else if (node instanceof ProcessingInstruction) { 98 kind = Type.PROCESSING_INSTRUCTION; 99 } else if (node instanceof Document) { 100 return docWrapper; 101 } else { 102 throwIllegalNode(node); return null; } 105 106 NodeWrapper wrapper = new NodeWrapper(node, parent, index); 107 wrapper.nodeKind = kind; 108 wrapper.docWrapper = docWrapper; 109 return wrapper; 110 } 111 112 private static void throwIllegalNode(Node node) { 113 String str = node == null ? 114 "NULL" : 115 node.getClass() + " instance " + node.toString(); 116 throw new IllegalArgumentException ("Bad node type in XOM! " + str); 117 } 118 119 122 123 public Configuration getConfiguration() { 124 return docWrapper.getConfiguration(); 125 } 126 127 130 131 public Object getUnderlyingNode() { 132 return node; 133 } 134 135 140 141 public NamePool getNamePool() { 142 return docWrapper.getNamePool(); 143 } 144 145 150 151 public int getNodeKind() { 152 return nodeKind; 153 } 154 155 158 159 public SequenceIterator getTypedValue() { 160 return SingletonIterator.makeIterator(new UntypedAtomicValue( 161 getStringValueCS())); 162 } 163 164 174 175 public Value atomize() throws XPathException { 176 return new UntypedAtomicValue(getStringValueCS()); 177 } 178 179 188 189 public int getTypeAnnotation() { 190 return -1; 191 } 192 193 200 201 public boolean isSameNodeInfo(NodeInfo other) { 202 if (other instanceof NodeWrapper) { 203 return node == ((NodeWrapper) other).node; } 205 return false; 206 } 207 208 216 217 public String getSystemId() { 218 return docWrapper.baseURI; 219 } 220 221 public void setSystemId(String uri) { 222 docWrapper.baseURI = uri; 223 } 224 225 229 230 public String getBaseURI() { 231 return node.getBaseURI(); 232 } 233 234 240 241 public int getLineNumber() { 242 return -1; 243 } 244 245 257 258 public int compareOrder(NodeInfo other) { 259 if (other instanceof NodeWrapper) { 260 return compareOrderFast(node,((NodeWrapper) other).node); 261 } else { 265 return -other.compareOrder(this); 267 } 268 } 269 270 private static int compareOrderFast(Node first, Node second) { 271 278 279 if (first == second) return 0; 282 283 ParentNode firstParent = first.getParent(); 284 ParentNode secondParent = second.getParent(); 285 if (firstParent == null) { 286 if (secondParent != null) return -1; return first.hashCode() - second.hashCode(); 289 } 290 291 if (secondParent == null) return +1; 293 if (firstParent == secondParent) { 295 int i1 = firstParent.indexOf(first); 296 int i2 = firstParent.indexOf(second); 297 298 if (i1 != -1) return (i2 != -1) ? i1 - i2 : +1; 302 if (i2 != -1) return -1; 303 304 Element elem = (Element) firstParent; 307 for (int i = elem.getAttributeCount(); --i >= 0;) { 308 Attribute attr = elem.getAttribute(i); 309 if (attr == second) return -1; 310 if (attr == first) return +1; 311 } 312 throw new IllegalStateException ("should be unreachable"); 313 } 314 315 int depth1 = 0; 317 int depth2 = 0; 318 Node p1 = first; 319 Node p2 = second; 320 while (p1 != null) { 321 depth1++; 322 p1 = p1.getParent(); 323 if (p1 == second) return +1; 324 } 325 while (p2 != null) { 326 depth2++; 327 p2 = p2.getParent(); 328 if (p2 == first) return -1; 329 } 330 331 p1 = first; 333 while (depth1 > depth2) { 334 p1 = p1.getParent(); 335 depth1--; 336 } 337 p2 = second; 338 while (depth2 > depth1) { 339 p2 = p2.getParent(); 340 depth2--; 341 } 342 343 while (true) { 345 firstParent = p1.getParent(); 346 secondParent = p2.getParent(); 347 if (firstParent == null || secondParent == null) { 348 return p1.hashCode() - p2.hashCode(); 351 } 353 if (firstParent == secondParent) { 354 return firstParent.indexOf(p1) - firstParent.indexOf(p2); 355 } 356 p1 = firstParent; 357 p2 = secondParent; 358 } 359 } 360 361 368 369 public String getStringValue() { 370 return node.getValue(); 371 } 372 373 377 378 public CharSequence getStringValueCS() { 379 return node.getValue(); 380 } 381 382 391 392 public int getNameCode() { 393 switch (nodeKind) { 394 case Type.ELEMENT: 395 case Type.ATTRIBUTE: 396 case Type.PROCESSING_INSTRUCTION: 397 return docWrapper.getNamePool().allocate(getPrefix(), getURI(), 398 getLocalPart()); 399 default: 400 return -1; 401 } 402 } 403 404 410 411 public int getFingerprint() { 412 int nc = getNameCode(); 413 if (nc == -1) { 414 return -1; 415 } 416 return nc & 0xfffff; 417 } 418 419 425 426 public String getLocalPart() { 427 switch (nodeKind) { 428 case Type.ELEMENT: 429 return ((Element) node).getLocalName(); 430 case Type.ATTRIBUTE: 431 return ((Attribute) node).getLocalName(); 432 case Type.PROCESSING_INSTRUCTION: 433 return ((ProcessingInstruction) node).getTarget(); 434 default: 435 return ""; 436 } 437 } 438 439 444 445 public String getPrefix() { 446 switch (nodeKind) { 447 case Type.ELEMENT: 448 return ((Element) node).getNamespacePrefix(); 449 case Type.ATTRIBUTE: 450 return ((Attribute) node).getNamespacePrefix(); 451 default: 452 return ""; 453 } 454 } 455 456 463 464 public String getURI() { 465 switch (nodeKind) { 466 case Type.ELEMENT: 467 return ((Element) node).getNamespaceURI(); 468 case Type.ATTRIBUTE: 469 return ((Attribute) node).getNamespaceURI(); 470 default: 471 return ""; 472 } 473 } 474 475 482 483 public String getDisplayName() { 484 switch (nodeKind) { 485 case Type.ELEMENT: 486 return ((Element) node).getQualifiedName(); 487 case Type.ATTRIBUTE: 488 return ((Attribute) node).getQualifiedName(); 489 case Type.PROCESSING_INSTRUCTION: 490 return ((ProcessingInstruction) node).getTarget(); 491 default: 492 return ""; 493 } 494 } 495 496 499 500 public NodeInfo getParent() { 501 if (parent == null) { 502 ParentNode p = node.getParent(); 503 if (p != null) parent = makeWrapper(p, docWrapper); 504 } 505 return parent; 506 } 507 508 511 512 public int getSiblingPosition() { 513 if (index != -1) return index; 514 switch (nodeKind) { 515 case Type.ATTRIBUTE: { 516 Attribute att = (Attribute) node; 517 Element p = (Element) att.getParent(); 518 if (p == null) return 0; 519 for (int i=p.getAttributeCount(); --i >= 0;) { 520 if (p.getAttribute(i) == att) { 521 index = i; 522 return i; 523 } 524 } 525 throw new IllegalStateException ("XOM node not linked to parent node"); 526 } 527 528 default: { 529 ParentNode p = node.getParent(); 530 int i = (p == null ? 0 : p.indexOf(node)); 531 if (i == -1) throw new IllegalStateException ("XOM node not linked to parent node"); 532 index = i; 533 return index; 534 } 535 } 536 } 537 538 547 548 public AxisIterator iterateAxis(byte axisNumber) { 549 return iterateAxis(axisNumber, AnyNodeTest.getInstance()); 550 } 551 552 563 564 public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) { 565 switch (axisNumber) { 566 case Axis.ANCESTOR: 567 return new AncestorAxisIterator(this, false, nodeTest); 568 569 case Axis.ANCESTOR_OR_SELF: 570 return new AncestorAxisIterator(this, true, nodeTest); 571 572 case Axis.ATTRIBUTE: 573 if (nodeKind != Type.ELEMENT || ((Element) node).getAttributeCount() == 0) { 574 return EmptyIterator.getInstance(); 575 } else { 576 return new AttributeAxisIterator(this, nodeTest); 577 } 578 579 case Axis.CHILD: 580 if (hasChildNodes()) { 581 return new ChildAxisIterator(this, true, true, nodeTest); 582 } else { 583 return EmptyIterator.getInstance(); 584 } 585 586 case Axis.DESCENDANT: 587 if (hasChildNodes()) { 588 return new DescendantAxisIterator(this, false, false, nodeTest); 589 } else { 590 return EmptyIterator.getInstance(); 591 } 592 593 case Axis.DESCENDANT_OR_SELF: 594 if (hasChildNodes()) { 595 return new DescendantAxisIterator(this, true, false, nodeTest); 596 } else { 597 return makeSingleIterator(this, nodeTest); 598 } 599 case Axis.FOLLOWING: 600 if (getParent() == null) { 601 return EmptyIterator.getInstance(); 602 } else { 603 return new DescendantAxisIterator(this, false, true, nodeTest); 604 } 605 606 case Axis.FOLLOWING_SIBLING: 607 if (nodeKind == Type.ATTRIBUTE || getParent() == null) { 608 return EmptyIterator.getInstance(); 609 } else { 610 return new ChildAxisIterator(this, false, true, nodeTest); 611 } 612 613 case Axis.NAMESPACE: 614 if (nodeKind == Type.ELEMENT) { 615 return new NamespaceIterator(this, nodeTest); 616 } else { 617 return EmptyIterator.getInstance(); 618 } 619 620 case Axis.PARENT: 621 if (getParent() == null) { 622 return EmptyIterator.getInstance(); 623 } else { 624 return makeSingleIterator(parent, nodeTest); 625 } 626 627 case Axis.PRECEDING: 628 return new PrecedingAxisIterator(this, false, nodeTest); 629 630 case Axis.PRECEDING_SIBLING: 631 if (nodeKind == Type.ATTRIBUTE || getParent() == null) { 632 return EmptyIterator.getInstance(); 633 } else { 634 return new ChildAxisIterator(this, false, false, nodeTest); 635 } 636 637 case Axis.SELF: 638 return makeSingleIterator(this, nodeTest); 639 640 case Axis.PRECEDING_OR_ANCESTOR: 641 return new PrecedingAxisIterator(this, true, nodeTest); 644 645 default: 646 throw new IllegalArgumentException ("Unknown axis number " + axisNumber); 647 } 648 } 649 650 private static AxisIterator makeSingleIterator(NodeWrapper wrapper, NodeTest nodeTest) { 651 if (nodeTest == AnyNodeTest.getInstance() || nodeTest.matches(wrapper)) 652 return SingletonIterator.makeIterator(wrapper); 653 else 654 return EmptyIterator.getInstance(); 655 } 656 657 664 665 public String getAttributeValue(int fingerprint) { 666 if (nodeKind == Type.ELEMENT) { 667 NamePool pool = docWrapper.getNamePool(); 668 String localName = pool.getLocalName(fingerprint); 669 String uri = pool.getURI(fingerprint); 670 Attribute att = ((Element) node).getAttribute(localName, uri); 671 if (att != null) return att.getValue(); 672 } 673 return null; 674 } 675 676 681 682 public NodeInfo getRoot() { 683 return docWrapper; 684 } 685 686 691 692 public DocumentInfo getDocumentRoot() { 693 return docWrapper; 694 } 695 696 701 702 public boolean hasChildNodes() { 703 return node.getChildCount() > 0; 704 } 705 706 712 713 public String generateId() { 714 return Navigator.getSequentialKey(this); 715 } 716 717 721 722 public int getDocumentNumber() { 723 return getDocumentRoot().getDocumentNumber(); 724 } 725 726 729 730 public void copy(Receiver out, int whichNamespaces, 731 boolean copyAnnotations, int locationId) throws XPathException { 732 Navigator.copy(this, out, docWrapper.getNamePool(), whichNamespaces, 733 copyAnnotations, locationId); 734 } 735 736 745 746 public void sendNamespaceDeclarations(Receiver out, boolean includeAncestors) 747 throws XPathException { 748 Navigator.sendNamespaceDeclarations(this, out, includeAncestors); 749 } 750 751 766 767 public int[] getDeclaredNamespaces(int[] buffer) { 768 if (node instanceof Element) { 769 Element elem = (Element)node; 770 int size = elem.getNamespaceDeclarationCount(); 771 if (size == 0) { 772 return EMPTY_NAMESPACE_LIST; 773 } 774 int[] result = (size <= buffer.length ? buffer : new int[size]); 775 NamePool pool = getNamePool(); 776 for (int i=0; i < size; i++) { 777 String prefix = elem.getNamespacePrefix(i); 778 String uri = elem.getNamespaceURI(prefix); 779 result[i] = pool.allocateNamespaceCode(prefix, uri); 780 } 781 if (size < result.length) { 782 result[size] = -1; 783 } 784 return result; 785 } else { 786 return null; 787 } 788 } 789 790 794 797 private final class AncestorAxisIterator implements AxisIterator { 798 799 private NodeWrapper start; 800 private boolean includeSelf; 801 802 private NodeInfo current; 803 804 private NodeTest nodeTest; 805 private int position; 806 807 public AncestorAxisIterator(NodeWrapper start, boolean includeSelf, NodeTest test) { 808 this.start = start; 810 if (test == AnyNodeTest.getInstance()) test = null; 811 this.nodeTest = test; 812 if (!includeSelf) this.current = start; 813 this.includeSelf = includeSelf; 814 this.position = 0; 815 } 816 817 public Item next() { 818 NodeInfo curr; 819 do { curr = advance(); 821 } 822 while (curr != null && nodeTest != null && (! nodeTest.matches(curr))); 823 824 if (curr != null) position++; 825 current = curr; 826 return curr; 827 } 828 829 private NodeInfo advance() { 830 if (current == null) 831 current = start; 832 else 833 current = current.getParent(); 834 835 return current; 836 } 837 838 public Item current() { 839 return current; 840 } 841 842 public int position() { 843 return position; 844 } 845 846 public SequenceIterator getAnother() { 847 return new AncestorAxisIterator(start, includeSelf, nodeTest); 848 } 849 850 859 860 public int getProperties() { 861 return 0; 862 } 863 864 } 866 869 870 private final class AttributeAxisIterator implements AxisIterator { 871 872 private NodeWrapper start; 873 874 private NodeInfo current; 875 private int cursor; 876 877 private NodeTest nodeTest; 878 private int position; 879 880 public AttributeAxisIterator(NodeWrapper start, NodeTest test) { 881 this.start = start; 883 if (test == AnyNodeTest.getInstance()) test = null; 884 this.nodeTest = test; 885 this.position = 0; 886 this.cursor = 0; 887 } 888 889 public Item next() { 890 NodeInfo curr; 891 do { curr = advance(); 893 } 894 while (curr != null && nodeTest != null && (! nodeTest.matches(curr))); 895 896 if (curr != null) position++; 897 current = curr; 898 return curr; 899 } 900 901 private NodeInfo advance() { 902 Element elem = (Element) start.node; 903 if (cursor == elem.getAttributeCount()) return null; 904 NodeInfo curr = makeWrapper(elem.getAttribute(cursor), docWrapper, start, cursor); 905 cursor++; 906 return curr; 907 } 908 909 public Item current() { 910 return current; 911 } 912 913 public int position() { 914 return position; 915 } 916 917 public SequenceIterator getAnother() { 918 return new AttributeAxisIterator(start, nodeTest); 919 } 920 921 930 931 public int getProperties() { 932 return 0; 933 } 934 935 } 937 944 private final class ChildAxisIterator implements AxisIterator { 945 946 private NodeWrapper start; 947 private NodeWrapper commonParent; 948 private int ix; 949 private boolean downwards; private boolean forwards; 952 private NodeInfo current; 953 private ParentNode par; 954 private int cursor; 955 956 private NodeTest nodeTest; 957 private int position; 958 959 private ChildAxisIterator(NodeWrapper start, boolean downwards, boolean forwards, NodeTest test) { 960 this.start = start; 961 this.downwards = downwards; 962 this.forwards = forwards; 963 964 if (test == AnyNodeTest.getInstance()) test = null; 965 this.nodeTest = test; 966 this.position = 0; 967 968 if (downwards) 969 commonParent = start; 970 else 971 commonParent = (NodeWrapper) start.getParent(); 972 973 par = (ParentNode) commonParent.node; 974 if (downwards) { 975 ix = (forwards ? 0 : par.getChildCount()); 976 } else { 977 ix = par.indexOf(start.node); 980 if (forwards) ix++; 981 } 982 cursor = ix; 983 if (!downwards && !forwards) ix--; 984 } 985 986 public Item next() { 987 NodeInfo curr; 988 do { curr = advance(); 990 } 991 while (curr != null && nodeTest != null && (! nodeTest.matches(curr))); 992 993 if (curr != null) position++; 994 current = curr; 995 return curr; 996 } 997 998 private NodeInfo advance() { 999 Node nextChild; 1000 do { 1001 if (forwards) { 1002 if (cursor == par.getChildCount()) return null; 1003 nextChild = par.getChild(cursor++); 1004 } else { if (cursor == 0) return null; 1006 nextChild = par.getChild(--cursor); 1007 } 1008 } while (nextChild instanceof DocType); 1009 1011 NodeInfo curr = makeWrapper(nextChild, docWrapper, commonParent, ix); 1012 ix += (forwards ? 1 : -1); 1013 return curr; 1014 } 1015 1016 public Item current() { 1017 return current; 1018 } 1019 1020 public int position() { 1021 return position; 1022 } 1023 1024 public SequenceIterator getAnother() { 1025 return new ChildAxisIterator(start, downwards, forwards, nodeTest); 1026 } 1027 1028 1037 1038 public int getProperties() { 1039 return 0; 1040 } 1041 1042 } 1043 1044 1050 private final class DescendantAxisIterator implements AxisIterator { 1051 1052 private NodeWrapper start; 1053 private boolean includeSelf; 1054 private boolean following; 1055 1056 private Node anchor; private Node currNode; 1058 private boolean moveToNextSibling; 1059 1060 private NodeInfo current; 1061 private NodeTest nodeTest; 1062 private int position; 1063 1064 private String testLocalName; 1065 private String testURI; 1066 1067 public DescendantAxisIterator(NodeWrapper start, boolean includeSelf, boolean following, NodeTest test) { 1068 this.start = start; 1069 this.includeSelf = includeSelf; 1070 this.following = following; 1071 this.moveToNextSibling = following; 1072 1073 if (!following) anchor = start.node; 1074 if (!includeSelf) currNode = start.node; 1075 1076 if (test == AnyNodeTest.getInstance()) { 1077 test = null; } 1079 else if (test instanceof NameTest) { 1080 NameTest nt = (NameTest) test; 1081 if (nt.getPrimitiveType() == Type.ELEMENT) { 1082 NamePool pool = getNamePool(); 1084 this.testLocalName = pool.getLocalName(nt.getFingerprint()); 1085 this.testURI = pool.getURI(nt.getFingerprint()); 1086 } 1087 } 1088 else if (test instanceof NodeKindTest) { 1089 if (test.getPrimitiveType() == Type.ELEMENT) { 1090 this.testLocalName = ""; 1092 this.testURI = null; 1093 } 1094 } 1095 this.nodeTest = test; 1096 this.position = 0; 1097 } 1098 1099 public Item next() { 1100 NodeInfo curr; 1101 do { curr = advance(); 1103 } 1104 while (curr != null && nodeTest != null && (! nodeTest.matches(curr))); 1105 1106 if (curr != null) position++; 1107 current = curr; 1108 return curr; 1109 } 1110 1111 private NodeInfo advance() { 1112 if (currNode == null) { currNode = start.node; 1114 return start; 1115 } 1116 1117 int i; 1118 do { 1119 i = 0; 1120 Node p = currNode; 1121 1122 if (p.getChildCount() == 0 || moveToNextSibling) { 1124 moveToNextSibling = false; while (true) { 1126 p = currNode.getParent(); 1128 if (p == null) return null; 1129 1130 i = currNode.getParent().indexOf(currNode) + 1; 1134 1135 if (i < p.getChildCount()) { 1136 break; } 1138 else { currNode = p; 1140 if (p == anchor) return null; 1142 } 1143 } 1144 } 1145 currNode = p.getChild(i); 1146 } while (!conforms(currNode)); 1147 1148 return makeWrapper(currNode, docWrapper, null, i); 1153 } 1154 1155 private boolean conforms(Node node) { 1157 if (this.testLocalName != null) { if (!(node instanceof Element)) return false; 1159 if (this.testURI == null) return true; 1161 Element elem = (Element) node; 1163 return this.testLocalName.equals(elem.getLocalName()) && 1164 this.testURI.equals(elem.getNamespaceURI()); 1165 } 1166 else { return !(node instanceof DocType); 1168 } 1169 } 1170 1171 public Item current() { 1172 return current; 1173 } 1174 1175 public int position() { 1176 return position; 1177 } 1178 1179 public SequenceIterator getAnother() { 1180 return new DescendantAxisIterator(start, includeSelf, following, nodeTest); 1181 } 1182 1183 1192 1193 public int getProperties() { 1194 return 0; 1195 } 1196 } 1197 1202 private final class PrecedingAxisIterator implements AxisIterator { 1203 1204 private NodeWrapper start; 1205 private boolean includeAncestors; 1206 1207 private Node currNode; 1208 private ParentNode nextAncestor; 1210 private NodeInfo current; 1211 private NodeTest nodeTest; 1212 private int position; 1213 1214 private String testLocalName; 1215 private String testURI; 1216 1217 public PrecedingAxisIterator(NodeWrapper start, boolean includeAncestors, NodeTest test) { 1218 this.start = start; 1219 this.includeAncestors = includeAncestors; 1220 this.currNode = start.node; 1221 if (includeAncestors) 1222 nextAncestor = null; 1223 else 1224 nextAncestor = start.node.getParent(); 1225 1226 if (test == AnyNodeTest.getInstance()) { test = null; } 1229 else if (test instanceof NameTest) { 1230 NameTest nt = (NameTest) test; 1231 if (nt.getPrimitiveType() == Type.ELEMENT) { NamePool pool = getNamePool(); 1234 this.testLocalName = pool.getLocalName(nt.getFingerprint()); 1235 this.testURI = pool.getURI(nt.getFingerprint()); 1236 } 1237 } 1238 else if (test instanceof NodeKindTest) { 1239 if (test.getPrimitiveType() == Type.ELEMENT) { this.testLocalName = ""; 1242 this.testURI = null; 1243 } 1244 } 1245 this.nodeTest = test; 1246 this.position = 0; 1247 } 1248 1249 public Item next() { 1250 NodeInfo curr; 1251 do { curr = advance(); 1253 } 1254 while (curr != null && nodeTest != null && (! nodeTest.matches(curr))); 1255 1256 if (curr != null) position++; 1257 current = curr; 1258 return curr; 1259 } 1260 1261 private NodeInfo advance() { 1263 int i; 1264 do { 1265 Node p; 1266 1267 while (true) { 1268 p = currNode.getParent(); 1271 if (p == null) return null; 1272 1273 i = currNode.getParent().indexOf(currNode) - 1; 1277 1278 if (i >= 0) { p = p.getChild(i); int j; 1281 while ((j = p.getChildCount()-1) >= 0) { p = p.getChild(j); 1283 i = j; 1284 } 1285 break; } 1287 else { if (p != nextAncestor) break; 1292 nextAncestor = nextAncestor.getParent(); 1293 currNode = p; 1294 } 1295 } 1296 currNode = p; 1297 1298 } while (!conforms(currNode)); 1299 1300 return makeWrapper(currNode, docWrapper, null, i); 1305 } 1306 1307 private boolean conforms(Node node) { 1310 if (this.testLocalName != null) { if (!(node instanceof Element)) return false; 1312 if (this.testURI == null) return true; 1314 Element elem = (Element) node; 1316 return this.testLocalName.equals(elem.getLocalName()) && 1317 this.testURI.equals(elem.getNamespaceURI()); 1318 } 1319 else { return !(node instanceof DocType); 1321 } 1322 } 1323 1324 public Item current() { 1325 return current; 1326 } 1327 1328 public int position() { 1329 return position; 1330 } 1331 1332 public SequenceIterator getAnother() { 1333 return new PrecedingAxisIterator(start, includeAncestors, nodeTest); 1334 } 1335 1336 1345 1346 public int getProperties() { 1347 return 0; 1348 } 1349 } 1350 1351} 1352 1353 | Popular Tags |