1 21 22 package nu.xom.tests; 23 24 import java.io.File ; 25 import java.io.IOException ; 26 import nu.xom.ParsingException; 27 28 import nu.xom.Attribute; 29 import nu.xom.Builder; 30 import nu.xom.Comment; 31 import nu.xom.DocType; 32 import nu.xom.Document; 33 import nu.xom.Element; 34 import nu.xom.Node; 35 import nu.xom.NodeFactory; 36 import nu.xom.Nodes; 37 import nu.xom.ProcessingInstruction; 38 import nu.xom.Text; 39 import nu.xom.ValidityException; 40 import nu.xom.XMLException; 41 42 52 public class NodeFactoryTest extends XOMTestCase { 53 54 55 private File data = new File ("data"); 56 57 58 public NodeFactoryTest(String name) { 59 super(name); 60 } 61 62 63 protected void setUp() { 64 numNodesInExternalDTDSubset = 0; 65 } 66 67 68 public void testSkippingComment() 69 throws IOException , ParsingException { 70 71 String data = "<a>1<!--tetetwkfjkl-->8</a>"; 72 Builder builder = new Builder(new CommentFilter()); 73 Document doc = builder.build(data, "http://www.example.org/"); 74 Element root = doc.getRootElement(); 75 assertEquals("Skipped comment interrupted text node", 76 2, root.getChildCount()); 77 assertEquals("18", doc.getValue()); 78 Node first = root.getChild(0); 79 assertEquals(first.getValue(), "1"); 80 Node second = root.getChild(1); 81 assertEquals(second.getValue(), "8"); 82 83 } 84 85 86 static class CommentFilter extends NodeFactory { 87 88 public Nodes makeComment(String data) { 89 return new Nodes(); 90 } 91 92 } 93 94 95 public void testCantAddOneElementMultipleTimes() 96 throws IOException , ParsingException { 97 98 String data = "<a><b>18</b></a>"; 99 Builder builder = new Builder(new SingleElementFactory()); 100 try { 101 builder.build(data, "http://www.example.org/"); 102 fail("Allowed one element in several places"); 103 } 104 catch (ParsingException success) { 105 assertNotNull(success.getMessage()); 106 } 107 108 } 109 110 111 public void testCantAddOneAttributeMultipleTimes() 112 throws IOException , ParsingException { 113 114 String data = "<a test=\"value\" name=\"data\"></a>"; 115 Builder builder = new Builder(new SingleAttributeFactory()); 116 try { 117 builder.build(data, "http://www.example.org/"); 118 fail("Allowed one attribute twice"); 119 } 120 catch (ParsingException success) { 121 assertNotNull(success.getMessage()); 122 } 123 124 } 125 126 127 private static class SingleElementFactory extends NodeFactory { 128 129 private Element test = new Element("test"); 130 131 public Element startMakingElement(String name, String namespace) { 132 return test; 133 } 134 135 } 136 137 138 private static class SingleAttributeFactory extends NodeFactory { 139 140 private Attribute test = new Attribute("limit", "none"); 141 142 public Nodes makeAttribute(String name, String URI, 143 String value, Attribute.Type type) { 144 return new Nodes(test); 145 } 146 147 } 148 149 150 public void testChangingElementName() 151 throws IOException , ParsingException { 152 153 String data 154 = "<a>1<b>2<a>3<b>4<a>innermost</a>5</b>6</a>7</b>8</a>"; 155 Builder builder = new Builder(new CFactory()); 156 Document doc = builder.build(data, "http://www.example.org/"); 157 Element root = doc.getRootElement(); 158 assertEquals("1234innermost5678", doc.getValue()); 159 assertEquals("c", root.getQualifiedName()); 160 assertEquals(3, root.getChildCount()); 161 Element b = (Element) root.getChild(1); 162 assertEquals("c", b.getQualifiedName()); 163 164 } 165 166 167 static class CFactory extends NodeFactory { 168 169 public Element startMakingElement( 170 String name, String namespace) { 171 return new Element("c"); 172 } 173 174 } 175 176 177 public void testMakeRoot() throws IOException , ParsingException { 178 179 String data = "<a><b>18</b></a>"; 180 Builder builder = new Builder(new CallsMakeRoot()); 181 Document doc = builder.build(data, "http://www.example.org/"); 182 Element root = doc.getRootElement(); 183 assertEquals("rootSubstitute", root.getQualifiedName()); 184 185 assertNotNull(root.getFirstChildElement("b")); 187 188 } 189 190 191 static class CallsMakeRoot extends NodeFactory { 192 193 public Element makeRootElement( 194 String name, String namepaceURI) { 195 return new Element("rootSubstitute"); 196 } 197 198 } 199 200 201 public void testSkippingProcessingInstruction() 202 throws IOException , ParsingException { 203 204 String data = "<a>1<?test some data?>8</a>"; 205 Builder builder = new Builder(new ProcessingInstructionFilter()); 206 Document doc = builder.build(data, "http://www.example.org/"); 207 Element root = doc.getRootElement(); 208 assertEquals( 209 "Skipped processing instruction interrupted text node", 210 2, root.getChildCount() 211 ); 212 assertEquals("18", doc.getValue()); 213 Node first = root.getChild(0); 214 assertEquals(first.getValue(), "1"); 215 Node second = root.getChild(1); 216 assertEquals(second.getValue(), "8"); 217 218 } 219 220 221 static class ProcessingInstructionFilter extends NodeFactory { 222 223 public Nodes makeProcessingInstruction( 224 String target, String data) { 225 return new Nodes(); 226 } 227 228 } 229 230 231 public void testSkipping2() throws IOException , ParsingException { 232 233 String data 234 = "<a>1<b>2<a>3<b>4<a>innermost</a>5</b>6</a>7</b>8</a>"; 235 Builder builder = new Builder(new BFilter()); 236 Document doc = builder.build(data, "http://www.example.org/"); 237 Element root = doc.getRootElement(); 238 assertEquals("1234innermost5678", doc.getValue()); 239 assertEquals(5, root.getChildCount()); 240 Node first = root.getChild(0); 241 assertEquals("1", first.getValue()); 242 Node middle = root.getChild(2); 243 assertEquals("34innermost56", middle.getValue()); 244 Node last = root.getChild(4); 245 assertEquals("8", last.getValue()); 246 247 Node innermost = middle.getChild(2); 248 assertEquals("innermost", innermost.getValue()); 249 Node inner1 = middle.getChild(0); 250 assertEquals("3", inner1.getValue()); 251 Node inner3 = middle.getChild(4); 252 assertEquals("6", inner3.getValue()); 253 254 } 255 256 257 static class BFilter extends NodeFactory { 258 259 public Element startMakingElement( 260 String name, String namespaceURI) { 261 if (name.equals("b")) return null; 262 return super.startMakingElement(name, namespaceURI); 263 } 264 265 } 266 267 268 public void testMinimalizedDocument() 269 throws IOException , ParsingException { 270 271 File input = new File (data, "entitytest.xml"); 272 Builder builder = new Builder(new MinimizingFactory()); 273 Document doc = builder.build(input); 274 assertEquals(1, doc.getChildCount()); 275 Element root = doc.getRootElement(); 276 assertEquals("root", root.getQualifiedName()); 277 assertEquals("", root.getNamespaceURI()); 278 assertEquals(0, root.getChildCount()); 279 assertEquals(0, root.getAttributeCount()); 280 281 } 282 283 284 public void testValidateWithFactory() 285 throws ParsingException, IOException { 286 Builder validator = new Builder(true, new MinimizingFactory()); 287 Document doc = validator.build("<!-- a comment --><!DOCTYPE root [" + 288 "<!ELEMENT root EMPTY>" + 289 "]>" + 290 "<root/><?a processing instruction?>", 291 "http://www.example.org/"); 292 assertEquals(1, doc.getChildCount()); 293 } 294 295 296 static class MinimizingFactory extends NodeFactory { 299 300 private Nodes empty = new Nodes(); 301 302 public Nodes makeComment(String data) { 303 return empty; 304 } 305 306 public Nodes makeText(String data) { 307 return empty; 308 } 309 310 public Nodes finishMakingElement(Element element) { 311 if (element.getParent() instanceof Document) { 312 return new Nodes(element); 313 } 314 return empty; 315 } 316 317 public Nodes makeAttribute(String name, String URI, 318 String value, Attribute.Type type) { 319 return empty; 320 } 321 322 public Nodes makeDocType(String rootElementName, 323 String publicID, String systemID) { 324 return empty; 325 } 326 327 public Nodes makeProcessingInstruction( 328 String target, String data) { 329 return empty; 330 } 331 332 } 333 334 335 public void testCDATASectionsCanBeOverridden() 336 throws ValidityException, ParsingException, IOException { 337 338 String data ="<root><![CDATA[text]]></root>"; 339 Builder builder = new Builder(new MinimizingFactory()); 340 Document doc = builder.build(data, "http://www.example.com"); 341 assertEquals("", doc.getValue()); 342 343 } 344 345 346 public void testNullRootNotAllowed() 347 throws IOException , ParsingException { 348 349 File input = new File (data, "entitytest.xml"); 350 Builder builder = new Builder(new NullElementFactory()); 351 try { 352 builder.build(input); 353 fail("Allowed null root"); 354 } 355 catch (ParsingException success) { 356 assertNotNull(success.getMessage()); 357 } 358 359 } 360 361 362 static class NullElementFactory extends NodeFactory { 365 366 public Element startMakingElement( 367 String name, String namespaceURI) { 368 return null; 369 } 370 371 } 372 373 374 public void testNullDocumentNotAllowed() 375 throws IOException , ParsingException { 376 377 File input = new File (data, "entitytest.xml"); 378 Builder builder = new Builder(new NullDocumentFactory()); 379 try { 380 builder.build(input); 381 fail("Allowed null document"); 382 } 383 catch (ParsingException success) { 384 assertTrue(success.getCause() instanceof NullPointerException ); 385 } 386 387 } 388 389 390 static class NullDocumentFactory extends NodeFactory { 393 394 public Document startMakingDocument() { 395 return null; 396 } 397 398 } 399 400 401 public void testSkipping() throws IOException , ParsingException { 402 403 String data = "<a>data<b>data<a>data</a>data</b>data</a>"; 404 Builder builder = new Builder(new BFilter()); 405 Document doc = builder.build(data, "http://www.example.org/"); 406 Element root = doc.getRootElement(); 407 assertEquals(5, root.getChildCount()); 408 assertEquals("datadatadatadatadata", root.getValue()); 409 Element middle = (Element) root.getChild(2); 410 assertEquals("data", middle.getValue()); 411 Node start = root.getChild(0); 412 Node end = root.getChild(4); 413 assertEquals("data", start.getValue()); 414 assertEquals("data", end.getValue()); 415 416 } 417 418 419 int numNodesInExternalDTDSubset = 0; 420 421 public void testDontReportCommentsAndProcessingInstructionsInExternalDTDSubset() 422 throws IOException , ParsingException { 423 424 File input = new File (data, "contentindtd.xml"); 425 Builder builder = new Builder(new Counter()); 426 builder.build(input); 427 assertEquals(0, numNodesInExternalDTDSubset); 428 429 } 430 431 432 private class Counter extends NodeFactory { 433 434 public Nodes makeComment(String data) { 435 numNodesInExternalDTDSubset++; 436 return super.makeComment(data); 437 } 438 439 public Nodes makeProcessingInstruction(String target, String data) { 440 numNodesInExternalDTDSubset++; 441 return super.makeProcessingInstruction(target, data); 442 } 443 444 } 445 446 447 public void testDontCoalesceTextNodes() 448 throws IOException , ParsingException { 449 450 String data = "<a>data<!-- comment--> data</a>"; 451 Builder builder = new Builder(new CommentFilter()); 452 Document doc = builder.build(data, "http://www.example.org/"); 453 Element root = doc.getRootElement(); 454 assertEquals(2, root.getChildCount()); 455 assertEquals("data data", root.getValue()); 456 Text text = (Text) root.getChild(0); 457 assertEquals("data", text.getValue()); 458 459 } 460 461 462 static class TripleElementFilter extends NodeFactory { 463 464 public Nodes finishMakingElement(Element element) { 465 Nodes result = new Nodes(element); 466 if (!(element.getParent() instanceof Document)) { 467 result.append(element.copy()); 468 result.append(element.copy()); 469 } 470 return result; 471 } 472 473 } 474 475 476 public void testTriple() 477 throws IOException , ParsingException { 478 479 String data = "<a><b><c/></b></a>"; 480 Builder builder = new Builder(new TripleElementFilter()); 481 Document doc = builder.build(data, "http://www.example.org/"); 482 Element root = doc.getRootElement(); 483 assertEquals(3, root.getChildCount()); 484 assertEquals("", root.getValue()); 485 Element b = (Element) root.getChild(0); 486 assertEquals("b", b.getLocalName()); 487 assertEquals( 488 "<a><b><c /><c /><c /></b><b><c /><c /><c /></b><b><c /><c /><c /></b></a>", 489 root.toXML()); 490 491 } 492 493 494 static class UncommentFilter extends NodeFactory { 495 496 public Nodes makeComment(String data) { 497 Nodes result = new Nodes(new Text(data)); 498 return result; 499 } 500 501 } 502 503 504 public void testUncomment() 505 throws ParsingException, IOException { 506 507 String data = "<!-- test --><a></a>"; 508 Builder builder = new Builder(new UncommentFilter()); 509 try { 510 builder.build(data, "http://www.example.org/"); 511 fail("built Text into prolog"); 512 } 513 catch (ParsingException success) { 514 assertNotNull(success.getMessage()); 515 } 516 517 } 518 519 520 static class DocumentFilter extends NodeFactory { 521 522 public Nodes makeComment(String data) { 523 Element root = new Element("root"); 524 Nodes result = new Nodes(new Document(root)); 525 return result; 526 } 527 528 } 529 530 531 public void testCantAddDocument() 532 throws ParsingException, IOException { 533 534 String data = "<a><!-- test --></a>"; 535 Builder builder = new Builder(new DocumentFilter()); 536 try { 537 builder.build(data, "http://www.example.org/"); 538 fail("built document into document"); 539 } 540 catch (ParsingException success) { 541 assertNotNull(success.getMessage()); 542 } 543 544 } 545 546 547 public void testCantAddTwoDoctypes() 548 throws ParsingException, IOException { 549 550 String data = "<!DOCTYPE a><a></a>"; 551 Builder builder = new Builder(new NodeFactory() { 552 553 public Nodes makeDocType(String name, String publicID, String systemID) { 554 Nodes result = new Nodes(); 555 result.append(new DocType(name, publicID, systemID)); 556 result.append(new Comment("sajdha")); 557 result.append(new DocType(name, publicID, systemID)); 558 return result; 559 } 560 561 }); 562 try { 563 builder.build(data, "http://www.example.org/"); 564 fail("built two doctypes"); 565 } 566 catch (ParsingException success) { 567 assertNotNull(success.getMessage()); 568 } 569 570 } 571 572 573 public void testChangeAttributesToElements() 574 throws ParsingException, IOException { 575 576 String data = "<a name=\"test\" value=\"data\"/>"; 577 Builder builder = new Builder(new NodeFactory() { 578 579 public Nodes makeAttribute(String name, String URI, 580 String value, Attribute.Type type) { 581 Nodes result = new Nodes(); 582 Element element = new Element(name, URI); 583 element.appendChild(value); 584 result.append(element); 585 return result; 586 } 587 588 }); 589 Document doc = builder.build(data, "http://www.example.org/"); 590 Element root = doc.getRootElement(); 591 assertEquals(2, root.getChildCount()); 592 Element name = root.getFirstChildElement("name"); 593 Element value = root.getFirstChildElement("value"); 594 assertEquals("test", name.getValue()); 595 assertEquals("data", value.getValue()); 596 assertEquals("name", name.getLocalName()); 597 assertEquals("value", value.getQualifiedName()); 598 599 } 600 601 602 public void testInsertElementsInInternalDTDSubsetViaProcessingInstruction() 603 throws ParsingException, IOException { 604 605 String data = "<!DOCTYPE a [<?target data?>]><a><b>data1</b><c>text</c></a>"; 606 Builder builder = new Builder(new NodeFactory() { 607 608 public Nodes makeProcessingInstruction(String target, String data) { 609 Nodes result = new Nodes(); 610 Element e = new Element(target); 611 e.appendChild(data); 612 result.append(e); 613 return result; 614 } 615 616 }); 617 try { 618 builder.build(data, "http://www.example.org/"); 619 fail("Allowed element in internal DTD subset via processing instruction"); 620 } 621 catch (ParsingException success) { 622 assertNotNull(success.getMessage()); 623 } 624 625 } 626 627 628 public void testInsertElementsInInternalDTDSubsetViaComment() 629 throws ParsingException, IOException { 630 631 String data = "<!DOCTYPE a [<!--data-->]><a><b>data1</b><c>text</c></a>"; 632 Builder builder = new Builder(new NodeFactory() { 633 634 public Nodes makeComment(String data) { 635 Nodes result = new Nodes(); 636 Element e = new Element("comment"); 637 e.appendChild(data); 638 result.append(e); 639 return result; 640 } 641 642 }); 643 try { 644 builder.build(data, "http://www.example.org/"); 645 fail("Allowed element in internal DTD subset via comment"); 646 } 647 catch (ParsingException success) { 648 assertNotNull(success.getMessage()); 649 } 650 651 } 652 653 654 public void testChangeElementsToAttributes() 655 throws ParsingException, IOException { 656 657 String data = "<a><b>data1</b><c>text</c></a>"; 658 Builder builder = new Builder(new NodeFactory() { 659 660 public Nodes finishMakingElement(Element element) { 661 Nodes result = new Nodes(); 662 if (element.getParent() instanceof Document) { 663 result.append(element); 664 } 665 else { 666 result.append(new Attribute(element.getLocalName(), element.getValue())); 667 } 668 return result; 669 } 670 671 }); 672 Document doc = builder.build(data, "http://www.example.org/"); 673 Element root = doc.getRootElement(); 674 assertEquals(0, root.getChildCount()); 675 assertEquals(2, root.getAttributeCount()); 676 assertEquals("data1", root.getAttribute("b").getValue()); 677 assertEquals("text", root.getAttribute("c").getValue()); 678 679 } 680 681 682 public void testChangeTextToAttributes() 683 throws ParsingException, IOException { 684 685 String data = "<a><b>data1</b><c>text</c></a>"; 686 Builder builder = new Builder(new NodeFactory() { 687 688 public Nodes makeText(String text) { 689 Nodes result = new Nodes(); 690 result.append(new Attribute("name", text)); 691 return result; 692 } 693 694 }); 695 Document doc = builder.build(data, "http://www.example.org/"); 696 Element root = doc.getRootElement(); 697 assertEquals(2, root.getChildCount()); 698 assertEquals(0, root.getAttributeCount()); 699 assertEquals("", root.getValue()); 700 Element b = root.getFirstChildElement("b"); 701 Element c = root.getFirstChildElement("c"); 702 assertEquals("data1", b.getAttribute("name").getValue()); 703 assertEquals("text", c.getAttribute("name").getValue()); 704 705 } 706 707 708 public void testChangeRootElementsToAttribute() 709 throws ParsingException, IOException { 710 711 String data = "<a><b>data1</b><c>text</c></a>"; 712 Builder builder = new Builder(new NodeFactory() { 713 714 public Nodes finishMakingElement(Element element) { 715 Nodes result = new Nodes(); 716 result.append(new Attribute(element.getLocalName(), element.getValue())); 717 return result; 718 } 719 720 }); 721 try { 722 builder.build(data, "http://www.example.org/"); 723 fail("replaced root element with attribute"); 724 } 725 catch (ParsingException success) { 726 assertNotNull(success.getMessage()); 727 } 728 729 } 730 731 732 public void testCantBypassMultipleParentChecks() 733 throws ParsingException, IOException { 734 735 String doc = "<root><a/><a/></root>"; 736 Builder builder = new Builder(new NodeFactory() { 737 738 private Element a = new Element("a"); 739 740 public Element startMakingElement(String name, String namespace) { 741 if (name.equals("a")) return a; 742 return new Element(name, namespace); 743 } 744 745 }); 746 try { 747 builder.build(doc, "http://www.example.org/"); 748 fail("built with multiple parents"); 749 } 750 catch (ParsingException success) { 751 assertNotNull(success.getMessage()); 752 } 753 754 } 755 756 757 public void testCantBypassMultipleParentChecksFromFinishMakingElement() 758 throws ParsingException, IOException { 759 760 String doc = "<root><a/><a/></root>"; 761 Builder builder = new Builder(new NodeFactory() { 762 763 private Element a = new Element("a"); 764 765 public Nodes finishMakingElement(Element element) { 766 if (element.getLocalName().equals("a")) return new Nodes(a); 767 else return new Nodes(element); 768 } 769 770 }); 771 try { 772 builder.build(doc, "http://www.example.org/"); 773 fail("built with multiple parents"); 774 } 775 catch (ParsingException success) { 776 assertNotNull(success.getMessage()); 777 } 778 779 } 780 781 782 public void testFinishMakingElementIsCalledForRootElement() 783 throws ParsingException, IOException { 784 785 String doc = "<root/>"; 786 Builder builder = new Builder(new NodeFactory() { 787 788 public Nodes finishMakingElement(Element element) { 789 throw new XMLException("Method was called"); 790 } 791 792 }); 793 try { 794 builder.build(doc, "http://www.example.org/"); 795 fail("Did not call finishMakingElement for root"); 796 } 797 catch (ParsingException success) { 798 assertEquals("Method was called", success.getMessage()); 799 } 800 801 } 802 803 804 public void testCanReplaceRootElementFromFinishMakingElement() 805 throws ParsingException, IOException { 806 807 String data = "<root/>"; 808 Builder builder = new Builder(new NodeFactory() { 809 810 public Nodes finishMakingElement(Element element) { 811 Nodes result = new Nodes(); 812 result.append(new Comment("test")); 813 result.append(new Element("newroot")); 814 result.append(new ProcessingInstruction("test", "test")); 815 return result; 816 } 817 818 }); 819 Document doc = builder.build(data, "http://www.example.org/"); 820 assertEquals("newroot", doc.getRootElement().getQualifiedName()); 821 assertEquals(3, doc.getChildCount()); 822 823 } 824 825 826 public void testCanAddAroundExistingRootElementFromFinishMakingElement() 827 throws ParsingException, IOException { 828 829 String data = "<root/>"; 830 Builder builder = new Builder(new NodeFactory() { 831 832 public Nodes finishMakingElement(Element element) { 833 Nodes result = new Nodes(); 834 result.append(new Comment("test")); 835 result.append(element); 836 result.append(new ProcessingInstruction("test", "test")); 837 return result; 838 } 839 840 }); 841 Document doc = builder.build(data, "http://www.example.org/"); 842 assertEquals("root", doc.getRootElement().getQualifiedName()); 843 assertEquals(3, doc.getChildCount()); 844 845 } 846 847 848 public void testCantReplaceRootElementWithNoElement() 849 throws ParsingException, IOException { 850 851 String data = "<root/>"; 852 Builder builder = new Builder(new NodeFactory() { 853 854 public Nodes finishMakingElement(Element element) { 855 Nodes result = new Nodes(); 856 result.append(new Comment("test")); 857 result.append(new ProcessingInstruction("test", "test")); 858 return result; 859 } 860 861 }); 862 try { 863 builder.build(data, "http://www.example.org/"); 864 fail("Built document without root element"); 865 } 866 catch (ParsingException success) { 867 assertNotNull(success.getMessage()); 868 } 869 870 } 871 872 873 public void testCantReplaceRootElementWithNothing() 874 throws ParsingException, IOException { 875 876 String data = "<root/>"; 877 Builder builder = new Builder(new NodeFactory() { 878 879 public Nodes finishMakingElement(Element element) { 880 return new Nodes(); 881 } 882 883 }); 884 try { 885 builder.build(data, "http://www.example.org/"); 886 fail("Built document without root element"); 887 } 888 catch (ParsingException success) { 889 assertNotNull(success.getMessage()); 890 } 891 892 } 893 894 895 public void testReplaceCommentWithAttribute() 896 throws ParsingException, IOException { 897 898 String data = "<root><!--comment--></root>"; 899 Builder builder = new Builder(new NodeFactory() { 900 901 public Nodes makeComment(String data) { 902 return new Nodes(new Attribute("name", "value")); 903 } 904 905 }); 906 Document doc = builder.build(data, "http://www.example.org/"); 907 Element root = doc.getRootElement(); 908 assertEquals(0, root.getChildCount()); 909 assertEquals(1, root.getAttributeCount()); 910 assertEquals("value", root.getAttribute("name").getValue()); 911 912 } 913 914 915 public void testReplaceProcessingInstructionWithAttribute() 916 throws ParsingException, IOException { 917 918 String data = "<root><?target data?></root>"; 919 Builder builder = new Builder(new NodeFactory() { 920 921 public Nodes makeProcessingInstruction(String target, String data) { 922 return new Nodes(new Attribute("name", "value")); 923 } 924 925 }); 926 Document doc = builder.build(data, "http://www.example.org/"); 927 Element root = doc.getRootElement(); 928 assertEquals(0, root.getChildCount()); 929 assertEquals(1, root.getAttributeCount()); 930 assertEquals("value", root.getAttribute("name").getValue()); 931 932 } 933 934 935 public void testReplaceProcessingInstructionWithText() 936 throws ParsingException, IOException { 937 938 String data = "<root><?target data?></root>"; 939 Builder builder = new Builder(new NodeFactory() { 940 941 public Nodes makeProcessingInstruction(String target, String data) { 942 return new Nodes(new Text(data)); 943 } 944 945 }); 946 Document doc = builder.build(data, "http://www.example.org/"); 947 Element root = doc.getRootElement(); 948 assertEquals(1, root.getChildCount()); 949 assertEquals(0, root.getAttributeCount()); 950 assertEquals("data", root.getValue()); 951 952 } 953 954 955 public void testCantReplaceRootElementWithTwoElements() 956 throws ParsingException, IOException { 957 958 String data = "<root/>"; 959 Builder builder = new Builder(new NodeFactory() { 960 961 public Nodes finishMakingElement(Element element) { 962 Nodes result = new Nodes(); 963 result.append(new Element("first")); 964 result.append(new Element("second")); 965 return result; 966 } 967 968 }); 969 try { 970 builder.build(data, "http://www.example.org/"); 971 fail("Built document without root element"); 972 } 973 catch (ParsingException success) { 974 assertNotNull(success.getMessage()); 975 } 976 977 } 978 979 980 public void testOrderOfCalls() 981 throws ParsingException, IOException { 982 983 String data = "<root>1<child>2</child>3</root>"; 984 Builder builder = new Builder(new NodeFactory() { 985 986 String s = ""; 987 988 public Nodes makeText(String text) { 989 s += text; 990 return super.makeText(text); 991 } 992 993 public Element startMakingElement(String name, String namespace) { 994 995 if (name.equals("child")) assertEquals("1", s); 996 return super.startMakingElement(name, namespace); 997 } 998 999 public Nodes finishMakingElement(Element element) { 1000 if (element.getLocalName().equals("child")) assertEquals("12", s); 1001 if (element.getLocalName().equals("root")) assertEquals("123", s); 1002 return super.finishMakingElement(element); 1003 } 1004 1005 }); 1006 builder.build(data, null); 1007 } 1008 1009 1010 public void testOrderOfCallsWithPI() 1011 throws ParsingException, IOException { 1012 1013 String data = "<root>1<?data ?>2</root>"; 1014 Builder builder = new Builder(new NodeFactory() { 1015 1016 String s = ""; 1017 1018 public Nodes makeText(String text) { 1019 s += text; 1020 return super.makeText(text); 1021 } 1022 1023 public Nodes makeProcessingInstruction(String target, String data) { 1024 1025 assertEquals("1", s); 1026 return new Nodes(); 1027 } 1028 1029 }); 1030 Document doc = builder.build(data, null); 1031 assertEquals(2, doc.getRootElement().getChildCount()); 1032 1033 } 1034 1035 1036 public void testOrderOfCallsWithComment() 1037 throws ParsingException, IOException { 1038 1039 String data = "<root>1<!-- test -->>2</root>"; 1040 Builder builder = new Builder(new NodeFactory() { 1041 1042 String s = ""; 1043 1044 public Nodes makeText(String text) { 1045 s += text; 1046 return super.makeText(text); 1047 } 1048 1049 public Nodes makeComment(String data) { 1050 1051 assertEquals("1", s); 1052 return new Nodes(); 1053 } 1054 1055 }); 1056 Document doc = builder.build(data, null); 1057 assertEquals(2, doc.getRootElement().getChildCount()); 1058 1059 } 1060 1061 1062} 1063 | Popular Tags |