1 16 package org.ccil.cowan.tagsoup; 17 import java.util.HashMap ; 18 import java.util.ArrayList ; 19 import java.io.*; 20 import java.net.URL ; 21 import java.net.URLConnection ; 22 import org.xml.sax.*; 23 import org.xml.sax.helpers.DefaultHandler ; 24 import org.xml.sax.ext.LexicalHandler ; 25 26 27 30 public class Parser extends DefaultHandler implements ScanHandler, XMLReader, LexicalHandler { 31 32 34 private ContentHandler theContentHandler = this; 35 private LexicalHandler theLexicalHandler = this; 36 private DTDHandler theDTDHandler = this; 37 private ErrorHandler theErrorHandler = this; 38 private EntityResolver theEntityResolver = this; 39 private Schema theSchema; 40 private Scanner theScanner; 41 private AutoDetector theAutoDetector; 42 private boolean namespaces = true; 44 private boolean ignoreBogons = false; 45 private boolean bogonsEmpty = true; 46 private boolean defaultAttributes = true; 47 private boolean translateColons = false; 48 private boolean restartElements = true; 49 private boolean ignorableWhitespace = false; 50 51 55 public final static String namespacesFeature = 56 "http://xml.org/sax/features/namespaces"; 57 58 63 public final static String namespacePrefixesFeature = 64 "http://xml.org/sax/features/namespace-prefixes"; 65 66 70 public final static String externalGeneralEntitiesFeature = 71 "http://xml.org/sax/features/external-general-entities"; 72 73 77 public final static String externalParameterEntitiesFeature = 78 "http://xml.org/sax/features/external-parameter-entities"; 79 80 86 public final static String isStandaloneFeature = 87 "http://xml.org/sax/features/is-standalone"; 88 89 93 public final static String lexicalHandlerParameterEntitiesFeature = 94 "http://xml.org/sax/features/lexical-handler/parameter-entities"; 95 96 101 public final static String resolveDTDURIsFeature = 102 "http://xml.org/sax/features/resolve-dtd-uris"; 103 104 112 public final static String stringInterningFeature = 113 "http://xml.org/sax/features/string-interning"; 114 115 120 121 public final static String useAttributes2Feature = 122 "http://xml.org/sax/features/use-attributes2"; 123 124 129 public final static String useLocator2Feature = 130 "http://xml.org/sax/features/use-locator2"; 131 132 137 public final static String useEntityResolver2Feature = 138 "http://xml.org/sax/features/use-entity-resolver2"; 139 140 144 public final static String validationFeature = 145 "http://xml.org/sax/features/validation"; 146 147 152 public final static String unicodeNormalizationCheckingFeature = 153 "http://xml.org/sax/features/unicode-normalization-checking"; 154 155 160 public final static String xmlnsURIsFeature = 161 "http://xml.org/sax/features/xmlns-uris"; 162 163 167 public final static String XML11Feature = 168 "http://xml.org/sax/features/xml-1.1"; 169 170 174 public final static String ignoreBogonsFeature = 175 "http://www.ccil.org/~cowan/tagsoup/features/ignore-bogons"; 176 177 182 public final static String bogonsEmptyFeature = 183 "http://www.ccil.org/~cowan/tagsoup/features/bogons-empty"; 184 185 189 public final static String defaultAttributesFeature = 190 "http://www.ccil.org/~cowan/tagsoup/features/default-attributes"; 191 192 196 public final static String translateColonsFeature = 197 "http://www.ccil.org/~cowan/tagsoup/features/translate-colons"; 198 199 203 public final static String restartElementsFeature = 204 "http://www.ccil.org/~cowan/tagsoup/features/restart-elements"; 205 206 213 public final static String ignorableWhitespaceFeature = 214 "http://www.ccil.org/~cowan/tagsoup/features/ignorable-whitespace"; 215 216 223 public final static String lexicalHandlerProperty = 224 "http://xml.org/sax/properties/lexical-handler"; 225 226 229 public final static String scannerProperty = 230 "http://www.ccil.org/~cowan/tagsoup/properties/scanner"; 231 232 235 public final static String schemaProperty = 236 "http://www.ccil.org/~cowan/tagsoup/properties/schema"; 237 238 241 public final static String autoDetectorProperty = 242 "http://www.ccil.org/~cowan/tagsoup/properties/auto-detector"; 243 244 private HashMap theFeatures = new HashMap (); 245 { 246 theFeatures.put(namespacesFeature, Boolean.TRUE); 247 theFeatures.put(namespacePrefixesFeature, Boolean.FALSE); 248 theFeatures.put(externalGeneralEntitiesFeature, Boolean.FALSE); 249 theFeatures.put(externalParameterEntitiesFeature, Boolean.FALSE); 250 theFeatures.put(isStandaloneFeature, Boolean.FALSE); 251 theFeatures.put(lexicalHandlerParameterEntitiesFeature, 252 Boolean.FALSE); 253 theFeatures.put(resolveDTDURIsFeature, Boolean.TRUE); 254 theFeatures.put(stringInterningFeature, Boolean.TRUE); 255 theFeatures.put(useAttributes2Feature, Boolean.FALSE); 256 theFeatures.put(useLocator2Feature, Boolean.FALSE); 257 theFeatures.put(useEntityResolver2Feature, Boolean.FALSE); 258 theFeatures.put(validationFeature, Boolean.FALSE); 259 theFeatures.put(xmlnsURIsFeature, Boolean.FALSE); 260 theFeatures.put(xmlnsURIsFeature, Boolean.FALSE); 261 theFeatures.put(XML11Feature, Boolean.FALSE); 262 theFeatures.put(ignoreBogonsFeature, Boolean.FALSE); 263 theFeatures.put(bogonsEmptyFeature, Boolean.TRUE); 264 theFeatures.put(defaultAttributesFeature, Boolean.TRUE); 265 theFeatures.put(translateColonsFeature, Boolean.FALSE); 266 theFeatures.put(restartElementsFeature, Boolean.TRUE); 267 theFeatures.put(ignorableWhitespaceFeature, Boolean.FALSE); 268 } 269 270 271 public boolean getFeature (String name) 272 throws SAXNotRecognizedException, SAXNotSupportedException { 273 Boolean b = (Boolean )theFeatures.get(name); 274 if (b == null) { 275 throw new SAXNotRecognizedException("Unknown feature " + name); 276 } 277 return b.booleanValue(); 278 } 279 280 public void setFeature (String name, boolean value) 281 throws SAXNotRecognizedException, SAXNotSupportedException { 282 Boolean b = (Boolean )theFeatures.get(name); 283 if (b == null) { 284 throw new SAXNotRecognizedException("Unknown feature " + name); 285 } 286 if (value) theFeatures.put(name, Boolean.TRUE); 287 else theFeatures.put(name, Boolean.FALSE); 288 289 if (name.equals(namespacesFeature)) namespaces = value; 290 else if (name.equals(ignoreBogonsFeature)) ignoreBogons = value; 291 else if (name.equals(bogonsEmptyFeature)) bogonsEmpty = value; 292 else if (name.equals(defaultAttributesFeature)) defaultAttributes = value; 293 else if (name.equals(translateColonsFeature)) translateColons = value; 294 else if (name.equals(restartElementsFeature)) restartElements = value; 295 else if (name.equals(ignorableWhitespaceFeature)) ignorableWhitespace = value; 296 } 297 298 public Object getProperty (String name) 299 throws SAXNotRecognizedException, SAXNotSupportedException { 300 if (name.equals(lexicalHandlerProperty)) { 301 return theLexicalHandler == this ? null : theLexicalHandler; 302 } 303 else if (name.equals(scannerProperty)) { 304 return theScanner; 305 } 306 else if (name.equals(schemaProperty)) { 307 return theSchema; 308 } 309 else if (name.equals(autoDetectorProperty)) { 310 return theAutoDetector; 311 } 312 else { 313 throw new SAXNotRecognizedException("Unknown property " + name); 314 } 315 } 316 317 public void setProperty (String name, Object value) 318 throws SAXNotRecognizedException, SAXNotSupportedException { 319 if (name.equals(lexicalHandlerProperty)) { 320 if (value instanceof LexicalHandler ) { 321 theLexicalHandler = (LexicalHandler )value; 322 } 323 else { 324 throw new SAXNotSupportedException("Your lexical handler is not a LexicalHandler"); 325 } 326 } 327 else if (name.equals(scannerProperty)) { 328 if (value instanceof Scanner) { 329 theScanner = (Scanner)value; 330 } 331 else { 332 throw new SAXNotSupportedException("Your scanner is not a Scanner"); 333 } 334 } 335 else if (name.equals(schemaProperty)) { 336 if (value instanceof Schema) { 337 theSchema = (Schema)value; 338 } 339 else { 340 throw new SAXNotSupportedException("Your schema is not a Schema"); 341 } 342 } 343 else if (name.equals(autoDetectorProperty)) { 344 if (value instanceof AutoDetector) { 345 theAutoDetector = (AutoDetector)value; 346 } 347 else { 348 throw new SAXNotSupportedException("Your auto-detector is not an AutoDetector"); 349 } 350 } 351 else { 352 throw new SAXNotRecognizedException("Unknown property " + name); 353 } 354 } 355 356 public void setEntityResolver (EntityResolver resolver) { 357 theEntityResolver = resolver; 358 } 359 360 public EntityResolver getEntityResolver () { 361 return (theEntityResolver == this) ? null : theEntityResolver; 362 } 363 364 public void setDTDHandler (DTDHandler handler) { 365 theDTDHandler = handler; 366 } 367 368 public DTDHandler getDTDHandler () { 369 return (theDTDHandler == this) ? null : theDTDHandler; 370 } 371 372 public void setContentHandler (ContentHandler handler) { 373 theContentHandler = handler; 374 } 375 376 public ContentHandler getContentHandler () { 377 return (theContentHandler == this) ? null : theContentHandler; 378 } 379 380 public void setErrorHandler (ErrorHandler handler) { 381 theErrorHandler = handler; 382 } 383 384 public ErrorHandler getErrorHandler () { 385 return (theErrorHandler == this) ? null : theErrorHandler; 386 } 387 388 public void parse (InputSource input) throws IOException, SAXException { 389 setup(); 390 Reader r = getReader(input); 391 theContentHandler.startDocument(); 392 theScanner.resetDocumentLocator(input.getPublicId(), input.getSystemId()); 393 if (theScanner instanceof Locator) { 394 theContentHandler.setDocumentLocator((Locator)theScanner); 395 } 396 if (!(theSchema.getURI().equals(""))) 397 theContentHandler.startPrefixMapping(theSchema.getPrefix(), 398 theSchema.getURI()); 399 theScanner.scan(r, this); 400 } 401 402 public void parse (String systemid) throws IOException, SAXException { 403 parse(new InputSource(systemid)); 404 } 405 406 private void setup() { 408 if (theSchema == null) theSchema = new HTMLSchema(); 409 if (theScanner == null) theScanner = new HTMLScanner(); 410 if (theAutoDetector == null) { 411 theAutoDetector = new AutoDetector() { 412 public Reader autoDetectingReader(InputStream i) { 413 return new InputStreamReader(i); 414 } 415 }; 416 } 417 theStack = new Element(theSchema.getElementType("<root>"), defaultAttributes); 418 thePCDATA = new Element(theSchema.getElementType("<pcdata>"), defaultAttributes); 419 theNewElement = null; 420 theAttributeName = null; 421 thePITarget = null; 422 theSaved = null; 423 theEntity = 0; 424 virginStack = true; 425 doctypename = doctypepublicid = doctypesystemid = null; 426 } 427 428 private Reader getReader(InputSource s) throws SAXException, IOException { 431 Reader r = s.getCharacterStream(); 432 InputStream i = s.getByteStream(); 433 String encoding = s.getEncoding(); 434 String publicid = s.getPublicId(); 435 String systemid = s.getSystemId(); 436 if (r == null) { 437 if (i == null) i = getInputStream(publicid, systemid); 438 if (encoding == null) { 440 r = theAutoDetector.autoDetectingReader(i); 441 } 442 else { 443 try { 444 r = new InputStreamReader(i, encoding); 445 } 446 catch (UnsupportedEncodingException e) { 447 r = new InputStreamReader(i); 448 } 449 } 450 } 451 return r; 453 } 454 455 private InputStream getInputStream(String publicid, String systemid) throws IOException, SAXException { 457 URL basis = new URL ("file", "", System.getProperty("user.dir") + "/."); 458 URL url = new URL (basis, systemid); 459 URLConnection c = url.openConnection(); 460 return c.getInputStream(); 461 } 462 464 466 private Element theNewElement = null; 467 private String theAttributeName = null; 468 private String doctypepublicid = null; 469 private String doctypesystemid = null; 470 private String doctypename = null; 471 private String thePITarget = null; 472 private Element theStack = null; 473 private Element theSaved = null; 474 private Element thePCDATA = null; 475 private char theEntity = 0; 476 477 public void adup(char[] buff, int offset, int length) throws SAXException { 478 if (theNewElement == null || theAttributeName == null) return; 479 theNewElement.setAttribute(theAttributeName, null, theAttributeName); 480 theAttributeName = null; 481 } 482 483 public void aname(char[] buff, int offset, int length) throws SAXException { 484 if (theNewElement == null) return; 485 theAttributeName = makeName(buff, offset, length); 486 } 488 489 public void aval(char[] buff, int offset, int length) throws SAXException { 490 if (theNewElement == null || theAttributeName == null) return; 491 String value = new String (buff, offset, length); 492 theNewElement.setAttribute(theAttributeName, null, value); 494 theAttributeName = null; 495 } 497 498 public void entity(char[] buff, int offset, int length) throws SAXException { 499 if (length < 1) { 500 theEntity = 0; 501 return; 502 } 503 String name = new String (buff, offset, length); 505 theEntity = theSchema.getEntity(name); 507 } 508 509 public void eof(char[] buff, int offset, int length) throws SAXException { 510 if (virginStack) rectify(thePCDATA); 511 while (theStack.next() != null) { 512 pop(); 513 } 514 if (!(theSchema.getURI().equals(""))) 515 theContentHandler.endPrefixMapping(theSchema.getPrefix()); 516 theContentHandler.endDocument(); 517 } 518 519 public void etag(char[] buff, int offset, int length) throws SAXException { 520 if (etag_cdata(buff, offset, length)) return; 521 etag_basic(buff, offset, length); 522 } 523 524 private static char[] etagchars = {'<', '/', '>'}; 525 public boolean etag_cdata(char[] buff, int offset, int length) throws SAXException { 526 String currentName = theStack.name(); 527 if ((theStack.flags() & Schema.F_CDATA) != 0) { 531 boolean realTag = (length == currentName.length()); 532 if (realTag) { 533 for (int i = 0; i < length; i++) { 534 if (Character.toLowerCase(buff[offset + i]) != Character.toLowerCase(currentName.charAt(i))) { 535 realTag = false; 536 break; 537 } 538 } 539 } 540 if (!realTag) { 541 theContentHandler.characters(etagchars, 0, 2); 542 theContentHandler.characters(buff, offset, length); 543 theContentHandler.characters(etagchars, 2, 1); 544 theScanner.startCDATA(); 545 return true; 546 } 547 } 548 return false; 549 } 550 551 public void etag_basic(char[] buff, int offset, int length) throws SAXException { 552 theNewElement = null; 553 String name; 554 if (length != 0) name = makeName(buff, offset, length); 555 else name = theStack.name(); 556 558 Element sp; 559 boolean inNoforce = false; 560 for (sp = theStack; sp != null; sp = sp.next()) { 561 if (sp.name().equals(name)) break; 562 if ((sp.flags() & Schema.F_NOFORCE) != 0) inNoforce = true; 563 } 564 565 if (sp == null) return; if (sp.next() == null || sp.next().next() == null) return; 567 if (inNoforce) { sp.preclose(); } 570 else { while (theStack != sp) { 572 restartablyPop(); 573 } 574 pop(); 575 } 576 while (theStack.isPreclosed()) { 578 pop(); 579 } 580 restart(null); 581 } 582 583 private void restart(Element e) throws SAXException { 586 while (theSaved != null && theStack.canContain(theSaved) && 587 (e == null || theSaved.canContain(e))) { 588 Element next = theSaved.next(); 589 push(theSaved); 590 theSaved = next; 591 } 592 } 593 594 private void pop() throws SAXException { 596 if (theStack == null) return; String name = theStack.name(); 598 String localName = theStack.localName(); 599 String namespace = theStack.namespace(); 600 if ((theStack.flags() & Schema.F_CDATA) != 0) { 602 theLexicalHandler.endCDATA(); 603 } 604 if (!namespaces) namespace = localName = ""; 605 theContentHandler.endElement(namespace, localName, name); 606 theStack = theStack.next(); 607 } 608 609 private void restartablyPop() throws SAXException { 611 Element popped = theStack; 612 pop(); 613 if (restartElements && (popped.flags() & Schema.F_RESTART) != 0) { 614 popped.anonymize(); 615 popped.setNext(theSaved); 616 theSaved = popped; 617 } 618 } 619 620 private boolean virginStack = true; 622 private void push(Element e) throws SAXException { 623 String name = e.name(); 624 String localName = e.localName(); 625 String namespace = e.namespace(); 626 e.clean(); 628 if (!namespaces) namespace = localName = ""; 629 if (virginStack && localName.equalsIgnoreCase(doctypename)) { 630 try { 631 theEntityResolver.resolveEntity(doctypepublicid, doctypesystemid); 632 } catch (IOException ew) { } } 634 theContentHandler.startElement(namespace, localName, name, e.atts()); 635 e.setNext(theStack); 636 theStack = e; 637 virginStack = false; 638 if ((theStack.flags() & Schema.F_CDATA) != 0) { 639 theScanner.startCDATA(); 640 theLexicalHandler.startCDATA(); 641 } 642 } 643 644 654 public void decl(char[] buff, int offset, int length) throws SAXException { 655 String s = new String (buff, offset, length); 656 String name = null; 657 String systemid = null; 658 String publicid = null; 659 String [] v = split(s); 660 if (v.length > 0 && "DOCTYPE".equals(v[0])) { 661 if (v.length > 1) { 662 name = v[1]; 663 if (v.length>3 && "SYSTEM".equals(v[2])) { 664 systemid = v[3]; 665 } 666 else if (v.length > 3 && "PUBLIC".equals(v[2])) { 667 publicid = v[3]; 668 if (v.length > 4) { 669 systemid = v[4]; 670 } 671 else { 672 systemid = ""; 673 } 674 } 675 } 676 } 677 publicid = trimquotes(publicid); 678 systemid = trimquotes(systemid); 679 if (name != null) { 680 publicid = cleanPublicid(publicid); 681 theLexicalHandler.startDTD(name, publicid, systemid); 682 theLexicalHandler.endDTD(); 683 doctypename = name; 684 doctypepublicid = publicid; 685 if (theScanner instanceof Locator) { doctypesystemid = ((Locator)theScanner).getSystemId(); 687 try { 688 doctypesystemid = new URL (new URL (doctypesystemid), systemid).toString(); 689 } catch (Exception e) {} 690 } 691 } 692 } 693 694 private static String trimquotes(String in) { 696 if (in == null) return in; 697 int length = in.length(); 698 if (length == 0) return in; 699 char s = in.charAt(0); 700 char e = in.charAt(length - 1); 701 if (s == e && (s == '\'' || s == '"')) { 702 in = in.substring(1, in.length() - 1); 703 } 704 return in; 705 } 706 707 private static String [] split(String val) throws IllegalArgumentException { 710 val = val.trim(); 711 if (val.length() == 0) { 712 return new String [0]; 713 } 714 else { 715 ArrayList l = new ArrayList (); 716 int s = 0; 717 int e = 0; 718 boolean sq = false; boolean dq = false; char lastc = 0; 721 int len = val.length(); 722 for (e=0; e < len; e++) { 723 char c = val.charAt(e); 724 if (!dq && c == '\'' && lastc != '\\') { 725 sq = !sq; 726 if (s < 0) s = e; 727 } 728 else if (!sq && c == '\"' && lastc != '\\') { 729 dq = !dq; 730 if (s < 0) s = e; 731 } 732 else if (!sq && !dq) { 733 if (Character.isWhitespace(c)) { 734 if (s >= 0) l.add(val.substring(s, e)); 735 s = -1; 736 } 737 else if (s < 0 && c != ' ') { 738 s = e; 739 } 740 } 741 lastc = c; 742 } 743 l.add(val.substring(s, e)); 744 return (String [])l.toArray(new String [0]); 745 } 746 } 747 748 private static String legal = 750 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-'()+,./:=?;!*#@$_%"; 751 752 private String cleanPublicid(String src) { 753 if (src == null) return null; 754 int len = src.length(); 755 StringBuffer dst = new StringBuffer (len); 756 boolean suppressSpace = true; 757 for (int i = 0; i < len; i++) { 758 char ch = src.charAt(i); 759 if (legal.indexOf(ch) != -1) { dst.append(ch); 761 suppressSpace = false; 762 } 763 else if (suppressSpace) { ; 765 } 766 else { 767 dst.append(' '); 768 suppressSpace = true; 769 } 770 } 771 return dst.toString().trim(); } 774 775 776 public void gi(char[] buff, int offset, int length) throws SAXException { 777 if (theNewElement != null) return; 778 String name = makeName(buff, offset, length); 779 if (name == null) return; 780 ElementType type = theSchema.getElementType(name); 781 if (type == null) { 782 if (ignoreBogons) return; 784 theSchema.elementType(name, bogonsEmpty ? Schema.M_EMPTY : Schema.M_ANY, Schema.M_ANY, 0); 785 type = theSchema.getElementType(name); 786 } 787 788 theNewElement = new Element(type, defaultAttributes); 789 } 791 792 public void pcdata(char[] buff, int offset, int length) throws SAXException { 793 if (length == 0) return; 794 boolean allWhite = true; 795 for (int i = 0; i < length; i++) { 796 if (!Character.isWhitespace(buff[offset+i])) { 797 allWhite = false; 798 } 799 } 800 if (allWhite && !theStack.canContain(thePCDATA)) { 801 if (ignorableWhitespace) { 802 theContentHandler.ignorableWhitespace(buff, offset, length); 803 } 804 } 805 else { 806 rectify(thePCDATA); 807 theContentHandler.characters(buff, offset, length); 808 } 809 } 810 811 public void pitarget(char[] buff, int offset, int length) throws SAXException { 812 if (theNewElement != null) return; 813 thePITarget = makeName(buff, offset, length); 814 } 815 816 public void pi(char[] buff, int offset, int length) throws SAXException { 817 if (theNewElement != null || thePITarget == null) return; 818 if (thePITarget.toLowerCase().equals("xml")) return; 819 if (length > 0 && buff[length - 1] == '?') length--; theContentHandler.processingInstruction(thePITarget, 822 new String (buff, offset, length)); 823 thePITarget = null; 824 } 825 826 public void stagc(char[] buff, int offset, int length) throws SAXException { 827 if (theNewElement == null) return; 829 rectify(theNewElement); 830 if (theStack.model() == Schema.M_EMPTY) { 831 etag_basic(buff, offset, length); 833 } 834 } 835 836 public void stage(char[] buff, int offset, int length) throws SAXException { 837 if (theNewElement == null) return; 839 rectify(theNewElement); 840 etag_basic(buff, offset, length); 842 } 843 844 private char[] theCommentBuffer = new char[2000]; 846 public void cmnt(char[] buff, int offset, int length) throws SAXException { 847 int postOffset = offset + length; 848 if (theCommentBuffer.length < postOffset * 2) { 849 theCommentBuffer = new char[postOffset * 2]; 850 } 851 int newSpaces = 0; 852 for (int i = offset, j = offset; i < postOffset; i++, j++) { 853 if (i == offset && buff[i] == '-') { 854 theCommentBuffer[j++] = ' '; 855 newSpaces++; 856 } 857 theCommentBuffer[j] = buff[i]; 858 if (buff[i] == '-') { 859 if (i == postOffset || buff[i+1] == '-') { 860 theCommentBuffer[j++] = ' '; 861 newSpaces++; 862 } 863 } 864 } 865 theLexicalHandler.comment(theCommentBuffer, offset, length + newSpaces); 866 } 867 868 private void rectify(Element e) throws SAXException { 871 Element sp; 872 while (true) { 873 for (sp = theStack; sp != null; sp = sp.next()) { 874 if (sp.canContain(e)) break; 875 } 876 if (sp != null) break; 877 ElementType parentType = e.parent(); 878 if (parentType == null) break; 879 Element parent = new Element(parentType, defaultAttributes); 880 parent.setNext(e); 882 e = parent; 883 } 884 if (sp == null) return; while (theStack != sp) { 886 if (theStack == null || theStack.next() == null || 887 theStack.next().next() == null) break; 888 restartablyPop(); 889 } 890 while (e != null) { 891 Element nexte = e.next(); 892 if (!e.name().equals("<pcdata>")) push(e); 893 e = nexte; 894 restart(e); 895 } 896 theNewElement = null; 897 } 898 899 public char getEntity() { 900 return theEntity; 901 } 902 903 private String makeName(char[] buff, int offset, int length) { 905 StringBuffer dst = new StringBuffer (length + 2); 906 boolean seenColon = false; 907 boolean start = true; 908 for (; length-- > 0; offset++) { 910 char ch = Character.toLowerCase(buff[offset]); 911 if (Character.isLetter(ch) || ch == '_') { 912 start = false; 913 dst.append(ch); 914 } 915 else if (Character.isDigit(ch) || ch == '-' || ch == '.') { 916 if (start) dst.append('_'); 917 start = false; 918 dst.append(ch); 919 } 920 else if (ch == ':' && !seenColon) { 921 seenColon = true; 922 if (start) dst.append('_'); 923 start = true; 924 dst.append(translateColons ? '_' : ch); 925 } 926 } 927 int dstLength = dst.length(); 928 if (dstLength == 0 || dst.charAt(dstLength - 1) == ':') dst.append('_'); 929 return dst.toString().intern(); 931 } 932 933 935 public void comment(char[] ch, int start, int length) throws SAXException { } 936 public void endCDATA() throws SAXException { } 937 public void endDTD() throws SAXException { } 938 public void endEntity(String name) throws SAXException { } 939 public void startCDATA() throws SAXException { } 940 public void startDTD(String name, String publicid, String systemid) throws SAXException { } 941 public void startEntity(String name) throws SAXException { } 942 943 } 944 | Popular Tags |