1 57 58 59 72 73 package com.sun.org.apache.xml.internal.serialize; 74 75 76 import java.io.IOException ; 77 import java.io.OutputStream ; 78 import java.io.Writer ; 79 import java.util.Enumeration ; 80 81 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter; 82 import org.w3c.dom.DOMError ; 83 import com.sun.org.apache.xerces.internal.util.NamespaceSupport; 84 import com.sun.org.apache.xerces.internal.util.SymbolTable; 85 import com.sun.org.apache.xerces.internal.util.XMLChar; 86 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 87 import com.sun.org.apache.xerces.internal.xni.NamespaceContext; 88 import org.w3c.dom.Attr ; 89 import org.w3c.dom.Element ; 90 import org.w3c.dom.NamedNodeMap ; 91 import org.w3c.dom.Node ; 92 import org.w3c.dom.traversal.NodeFilter; 93 import org.xml.sax.AttributeList ; 94 import org.xml.sax.Attributes ; 95 import org.xml.sax.SAXException ; 96 import org.xml.sax.helpers.AttributesImpl ; 97 98 130 public class XMLSerializer 131 extends BaseMarkupSerializer { 132 133 137 protected static final boolean DEBUG = false; 138 139 143 147 148 protected NamespaceSupport fNSBinder; 149 150 151 protected NamespaceSupport fLocalNSBinder; 152 153 154 protected SymbolTable fSymbolTable; 155 156 protected final static String PREFIX = "NS"; 157 158 165 protected boolean fNamespaces = false; 166 167 168 private boolean fPreserveSpace; 169 170 171 176 public XMLSerializer() { 177 super( new OutputFormat( Method.XML, null, false ) ); 178 } 179 180 181 186 public XMLSerializer( OutputFormat format ) { 187 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 188 _format.setMethod( Method.XML ); 189 } 190 191 192 200 public XMLSerializer( Writer writer, OutputFormat format ) { 201 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 202 _format.setMethod( Method.XML ); 203 setOutputCharStream( writer ); 204 } 205 206 207 215 public XMLSerializer( OutputStream output, OutputFormat format ) { 216 super( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 217 _format.setMethod( Method.XML ); 218 setOutputByteStream( output ); 219 } 220 221 222 public void setOutputFormat( OutputFormat format ) { 223 super.setOutputFormat( format != null ? format : new OutputFormat( Method.XML, null, false ) ); 224 } 225 226 227 234 public void setNamespaces (boolean namespaces){ 235 fNamespaces = namespaces; 236 if (fNSBinder == null) { 237 fNSBinder = new NamespaceSupport(); 238 fLocalNSBinder = new NamespaceSupport(); 239 fSymbolTable = new SymbolTable(); 240 } 241 } 242 243 247 248 public void startElement( String namespaceURI, String localName, 249 String rawName, Attributes attrs ) 250 throws SAXException 251 { 252 int i; 253 boolean preserveSpace; 254 ElementState state; 255 String name; 256 String value; 257 boolean addNSAttr = false; 258 259 if (DEBUG) { 260 System.out.println("==>startElement("+namespaceURI+","+localName+ 261 ","+rawName+")"); 262 } 263 264 try { 265 if (_printer == null) { 266 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "NoWriterSupplied", null); 267 throw new IllegalStateException (msg); 268 } 269 270 state = getElementState(); 271 if (isDocumentState()) { 272 if (! _started) 277 startDocument( ( localName == null || localName.length() == 0 ) ? rawName : localName ); 278 } else { 279 if (state.empty) 283 _printer.printText( '>' ); 284 if (state.inCData) { 286 _printer.printText( "]]>" ); 287 state.inCData = false; 288 } 289 if (_indenting && ! state.preserveSpace && 293 ( state.empty || state.afterElement || state.afterComment)) 294 _printer.breakLine(); 295 } 296 preserveSpace = state.preserveSpace; 297 298 attrs = extractNamespaces(attrs); 301 302 if (rawName == null || rawName.length() == 0) { 305 if (localName == null) { 306 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "NoName", null); 307 throw new SAXException (msg); 308 } 309 if (namespaceURI != null && ! namespaceURI.equals( "" )) { 310 String prefix; 311 prefix = getPrefix( namespaceURI ); 312 if (prefix != null && prefix.length() > 0) 313 rawName = prefix + ":" + localName; 314 else 315 rawName = localName; 316 } else 317 rawName = localName; 318 addNSAttr = true; 319 } 320 321 _printer.printText( '<' ); 322 _printer.printText( rawName ); 323 _printer.indent(); 324 325 if (attrs != null) { 329 for (i = 0 ; i < attrs.getLength() ; ++i) { 330 _printer.printSpace(); 331 332 name = attrs.getQName( i ); 333 if (name != null && name.length() == 0) { 334 String prefix; 335 String attrURI; 336 337 name = attrs.getLocalName( i ); 338 attrURI = attrs.getURI( i ); 339 if (( attrURI != null && attrURI.length() != 0 ) && 340 ( namespaceURI == null || namespaceURI.length() == 0 || 341 ! attrURI.equals( namespaceURI ) )) { 342 prefix = getPrefix( attrURI ); 343 if (prefix != null && prefix.length() > 0) 344 name = prefix + ":" + name; 345 } 346 } 347 348 value = attrs.getValue( i ); 349 if (value == null) 350 value = ""; 351 _printer.printText( name ); 352 _printer.printText( "=\"" ); 353 printEscaped( value ); 354 _printer.printText( '"' ); 355 356 if (name.equals( "xml:space" )) { 360 if (value.equals( "preserve" )) 361 preserveSpace = true; 362 else 363 preserveSpace = _format.getPreserveSpace(); 364 } 365 } 366 } 367 368 if (_prefixes != null) { 369 Enumeration keys; 370 371 keys = _prefixes.keys(); 372 while (keys.hasMoreElements()) { 373 _printer.printSpace(); 374 value = (String ) keys.nextElement(); 375 name = (String ) _prefixes.get( value ); 376 if (name.length() == 0) { 377 _printer.printText( "xmlns=\"" ); 378 printEscaped( value ); 379 _printer.printText( '"' ); 380 } else { 381 _printer.printText( "xmlns:" ); 382 _printer.printText( name ); 383 _printer.printText( "=\"" ); 384 printEscaped( value ); 385 _printer.printText( '"' ); 386 } 387 } 388 } 389 390 state = enterElementState( namespaceURI, localName, rawName, preserveSpace ); 394 name = ( localName == null || localName.length() == 0 ) ? rawName : namespaceURI + "^" + localName; 395 state.doCData = _format.isCDataElement( name ); 396 state.unescaped = _format.isNonEscapingElement( name ); 397 } catch (IOException except) { 398 throw new SAXException ( except ); 399 } 400 } 401 402 403 public void endElement( String namespaceURI, String localName, 404 String rawName ) 405 throws SAXException 406 { 407 try { 408 endElementIO( namespaceURI, localName, rawName ); 409 } catch (IOException except) { 410 throw new SAXException ( except ); 411 } 412 } 413 414 415 public void endElementIO( String namespaceURI, String localName, 416 String rawName ) 417 throws IOException 418 { 419 ElementState state; 420 if (DEBUG) { 421 System.out.println("==>endElement: " +rawName); 422 } 423 _printer.unindent(); 427 state = getElementState(); 428 if (state.empty) { 429 _printer.printText( "/>" ); 430 } else { 431 if (state.inCData) 433 _printer.printText( "]]>" ); 434 if (_indenting && ! state.preserveSpace && (state.afterElement || state.afterComment)) 438 _printer.breakLine(); 439 _printer.printText( "</" ); 440 _printer.printText( state.rawName ); 441 _printer.printText( '>' ); 442 } 443 state = leaveElementState(); 446 state.afterElement = true; 447 state.afterComment = false; 448 state.empty = false; 449 if (isDocumentState()) 450 _printer.flush(); 451 } 452 453 454 458 459 public void startElement( String tagName, AttributeList attrs ) 460 throws SAXException 461 { 462 int i; 463 boolean preserveSpace; 464 ElementState state; 465 String name; 466 String value; 467 468 469 if (DEBUG) { 470 System.out.println("==>startElement("+tagName+")"); 471 } 472 473 try { 474 if (_printer == null) { 475 String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.SERIALIZER_DOMAIN, "NoWriterSupplied", null); 476 throw new IllegalStateException (msg); 477 } 478 479 state = getElementState(); 480 if (isDocumentState()) { 481 if (! _started) 486 startDocument( tagName ); 487 } else { 488 if (state.empty) 492 _printer.printText( '>' ); 493 if (state.inCData) { 495 _printer.printText( "]]>" ); 496 state.inCData = false; 497 } 498 if (_indenting && ! state.preserveSpace && 502 ( state.empty || state.afterElement || state.afterComment)) 503 _printer.breakLine(); 504 } 505 preserveSpace = state.preserveSpace; 506 507 510 _printer.printText( '<' ); 511 _printer.printText( tagName ); 512 _printer.indent(); 513 514 if (attrs != null) { 518 for (i = 0 ; i < attrs.getLength() ; ++i) { 519 _printer.printSpace(); 520 name = attrs.getName( i ); 521 value = attrs.getValue( i ); 522 if (value != null) { 523 _printer.printText( name ); 524 _printer.printText( "=\"" ); 525 printEscaped( value ); 526 _printer.printText( '"' ); 527 } 528 529 if (name.equals( "xml:space" )) { 533 if (value.equals( "preserve" )) 534 preserveSpace = true; 535 else 536 preserveSpace = _format.getPreserveSpace(); 537 } 538 } 539 } 540 state = enterElementState( null, null, tagName, preserveSpace ); 544 state.doCData = _format.isCDataElement( tagName ); 545 state.unescaped = _format.isNonEscapingElement( tagName ); 546 } catch (IOException except) { 547 throw new SAXException ( except ); 548 } 549 550 } 551 552 553 public void endElement( String tagName ) 554 throws SAXException 555 { 556 endElement( null, null, tagName ); 557 } 558 559 560 561 565 566 578 protected void startDocument( String rootTagName ) 579 throws IOException 580 { 581 int i; 582 String dtd; 583 584 dtd = _printer.leaveDTD(); 585 if (! _started) { 586 587 if (! _format.getOmitXMLDeclaration()) { 588 StringBuffer buffer; 589 590 buffer = new StringBuffer ( "<?xml version=\"" ); 593 if (_format.getVersion() != null) 594 buffer.append( _format.getVersion() ); 595 else 596 buffer.append( "1.0" ); 597 buffer.append( '"' ); 598 String format_encoding = _format.getEncoding(); 599 if (format_encoding != null) { 600 buffer.append( " encoding=\"" ); 601 buffer.append( format_encoding ); 602 buffer.append( '"' ); 603 } 604 if (_format.getStandalone() && _docTypeSystemId == null && 605 _docTypePublicId == null) 606 buffer.append( " standalone=\"yes\"" ); 607 buffer.append( "?>" ); 608 _printer.printText( buffer ); 609 _printer.breakLine(); 610 } 611 612 if (! _format.getOmitDocumentType()) { 613 if (_docTypeSystemId != null) { 614 _printer.printText( "<!DOCTYPE " ); 618 _printer.printText( rootTagName ); 619 if (_docTypePublicId != null) { 620 _printer.printText( " PUBLIC " ); 621 printDoctypeURL( _docTypePublicId ); 622 if (_indenting) { 623 _printer.breakLine(); 624 for (i = 0 ; i < 18 + rootTagName.length() ; ++i) 625 _printer.printText( " " ); 626 } else 627 _printer.printText( " " ); 628 printDoctypeURL( _docTypeSystemId ); 629 } else { 630 _printer.printText( " SYSTEM " ); 631 printDoctypeURL( _docTypeSystemId ); 632 } 633 634 if (dtd != null && dtd.length() > 0) { 637 _printer.printText( " [" ); 638 printText( dtd, true, true ); 639 _printer.printText( ']' ); 640 } 641 642 _printer.printText( ">" ); 643 _printer.breakLine(); 644 } else if (dtd != null && dtd.length() > 0) { 645 _printer.printText( "<!DOCTYPE " ); 646 _printer.printText( rootTagName ); 647 _printer.printText( " [" ); 648 printText( dtd, true, true ); 649 _printer.printText( "]>" ); 650 _printer.breakLine(); 651 } 652 } 653 } 654 _started = true; 655 serializePreRoot(); 657 } 658 659 660 665 protected void serializeElement( Element elem ) 666 throws IOException 667 { 668 Attr attr; 669 NamedNodeMap attrMap; 670 int i; 671 Node child; 672 ElementState state; 673 String name; 674 String value; 675 String tagName; 676 677 String prefix, localUri; 678 String uri; 679 if (fNamespaces) { 680 fLocalNSBinder.reset(); 684 685 fNSBinder.pushContext(); 687 } 688 689 if (DEBUG) { 690 System.out.println("==>startElement: " +elem.getNodeName() +" ns="+elem.getNamespaceURI()); 691 } 692 tagName = elem.getTagName(); 693 state = getElementState(); 694 if (isDocumentState()) { 695 700 if (! _started) { 701 startDocument( tagName); 702 } 703 } else { 704 if (state.empty) 708 _printer.printText( '>' ); 709 if (state.inCData) { 711 _printer.printText( "]]>" ); 712 state.inCData = false; 713 } 714 if (_indenting && ! state.preserveSpace && 718 ( state.empty || state.afterElement || state.afterComment)) 719 _printer.breakLine(); 720 } 721 722 fPreserveSpace = state.preserveSpace; 725 726 727 int length = 0; 728 attrMap = null; 729 if (elem.hasAttributes()) { 731 attrMap = elem.getAttributes(); 732 length = attrMap.getLength(); 733 } 734 735 if (!fNamespaces) { 737 _printer.printText( '<' ); 739 _printer.printText( tagName ); 740 _printer.indent(); 741 742 for ( i = 0 ; i < length ; ++i ) { 746 attr = (Attr ) attrMap.item( i ); 747 name = attr.getName(); 748 value = attr.getValue(); 749 if ( value == null ) 750 value = ""; 751 printAttribute (name, value, attr.getSpecified(), attr); 752 } 753 } else { 755 759 764 for (i = 0;i < length;i++) { 765 766 attr = (Attr ) attrMap.item( i ); 767 uri = attr.getNamespaceURI(); 768 if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) { 770 771 value = attr.getNodeValue(); 772 if (value == null) { 773 value=XMLSymbols.EMPTY_STRING; 774 } 775 776 if (value.equals(NamespaceContext.XMLNS_URI)) { 777 if (fDOMErrorHandler != null) { 778 String msg = DOMMessageFormatter.formatMessage( 779 DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null ); 780 modifyDOMError(msg, DOMError.SEVERITY_ERROR, attr); 781 boolean continueProcess = fDOMErrorHandler.handleError(fDOMError); 782 if (!continueProcess) { 783 throw new RuntimeException ( 785 DOMMessageFormatter.formatMessage( 786 DOMMessageFormatter.SERIALIZER_DOMAIN, 787 "SerializationStopped", null)); 788 } 789 } 790 } else { 791 prefix = attr.getPrefix(); 792 prefix = (prefix == null || 793 prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix); 794 String localpart = fSymbolTable.addSymbol( attr.getLocalName()); 795 if (prefix == XMLSymbols.PREFIX_XMLNS) { value = fSymbolTable.addSymbol(value); 797 if (value.length() != 0) { 799 fNSBinder.declarePrefix(localpart, value); 800 } else { 801 } 804 continue; 805 } else { 808 value = fSymbolTable.addSymbol(value); 809 fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, value); 810 continue; 811 } 812 } } } 816 uri = elem.getNamespaceURI(); 820 prefix = elem.getPrefix(); 821 822 if ((uri !=null && prefix !=null ) && uri.length() == 0 && prefix.length()!=0) { 828 prefix = null; 832 _printer.printText( '<' ); 833 _printer.printText( elem.getLocalName() ); 834 _printer.indent(); 835 } else { 836 _printer.printText( '<' ); 837 _printer.printText( tagName ); 838 _printer.indent(); 839 } 840 841 842 868 869 if (uri != null) { uri = fSymbolTable.addSymbol(uri); 871 prefix = (prefix == null || 872 prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix); 873 if (fNSBinder.getURI(prefix) == uri) { 874 880 } else { 881 printNamespaceAttr(prefix, uri); 885 fLocalNSBinder.declarePrefix(prefix, uri); 886 fNSBinder.declarePrefix(prefix, uri); 887 } 888 } else { if (elem.getLocalName() == null) { 890 if (fDOMErrorHandler != null) { 892 String msg = DOMMessageFormatter.formatMessage( 893 DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName", 894 new Object []{elem.getNodeName()}); 895 modifyDOMError(msg,DOMError.SEVERITY_ERROR, elem); 896 boolean continueProcess = fDOMErrorHandler.handleError(fDOMError); 897 if (!continueProcess) { 899 throw new RuntimeException ( 900 DOMMessageFormatter.formatMessage( 901 DOMMessageFormatter.SERIALIZER_DOMAIN, 902 "SerializationStopped", null)); 903 } 904 } 905 } else { uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING); 907 908 if (uri !=null && uri.length() > 0) { 909 printNamespaceAttr(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); 912 fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); 913 fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); 914 } 915 } 916 } 917 918 919 924 for (i = 0; i < length; i++) { 925 926 attr = (Attr ) attrMap.item( i ); 927 value = attr.getValue(); 928 name = attr.getNodeName(); 929 930 uri = attr.getNamespaceURI(); 931 932 if (uri !=null && uri.length() == 0) { 934 uri=null; 935 name=attr.getLocalName(); 937 } 938 939 if (DEBUG) { 940 System.out.println("==>process attribute: "+attr.getNodeName()); 941 } 942 if (value == null) { 944 value=XMLSymbols.EMPTY_STRING; 945 } 946 947 if (uri != null) { prefix = attr.getPrefix(); 949 prefix = prefix == null ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix); 950 String localpart = fSymbolTable.addSymbol( attr.getLocalName()); 951 952 953 954 if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) { 958 prefix = attr.getPrefix(); 960 prefix = (prefix == null || 961 prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix); 962 localpart = fSymbolTable.addSymbol( attr.getLocalName()); 963 if (prefix == XMLSymbols.PREFIX_XMLNS) { localUri = fLocalNSBinder.getURI(localpart); value = fSymbolTable.addSymbol(value); 966 if (value.length() != 0 ) { 967 if (localUri == null) { 968 printNamespaceAttr(localpart, value); 970 fLocalNSBinder.declarePrefix(localpart, value); 977 } 978 } else { 979 } 982 continue; 983 } else { 986 uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING); 987 localUri=fLocalNSBinder.getURI(XMLSymbols.EMPTY_STRING); 988 value = fSymbolTable.addSymbol(value); 989 if (localUri == null ){ 990 printNamespaceAttr(XMLSymbols.EMPTY_STRING, value); 992 } 995 continue; 996 } 997 998 } 999 uri = fSymbolTable.addSymbol(uri); 1000 1001 String declaredURI = fNSBinder.getURI(prefix); 1003 1004 if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) { 1005 1011 name = attr.getNodeName(); 1012 String declaredPrefix = fNSBinder.getPrefix(uri); 1015 1016 if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) { 1017 prefix = declaredPrefix; 1019 name=prefix+":"+localpart; 1020 } else { 1021 if (DEBUG) { 1022 System.out.println("==> cound not find prefix for the attribute: " +prefix); 1023 } 1024 1025 if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) { 1026 1028 } else { 1030 int counter = 1; 1033 prefix = fSymbolTable.addSymbol(PREFIX + counter++); 1034 while (fLocalNSBinder.getURI(prefix)!=null) { 1035 prefix = fSymbolTable.addSymbol(PREFIX +counter++); 1036 } 1037 name=prefix+":"+localpart; 1038 } 1039 printNamespaceAttr(prefix, uri); 1041 value = fSymbolTable.addSymbol(value); 1042 fLocalNSBinder.declarePrefix(prefix, value); 1043 fNSBinder.declarePrefix(prefix, uri); 1044 } 1045 1046 } 1048 1049 printAttribute (name, (value==null)?XMLSymbols.EMPTY_STRING:value, attr.getSpecified(), attr); 1050 } else { if (attr.getLocalName() == null) { 1052 if (fDOMErrorHandler != null) { 1053 String msg = DOMMessageFormatter.formatMessage( 1054 DOMMessageFormatter.DOM_DOMAIN, 1055 "NullLocalAttrName", new Object []{attr.getNodeName()}); 1056 modifyDOMError(msg, DOMError.SEVERITY_ERROR, attr); 1057 boolean continueProcess = fDOMErrorHandler.handleError(fDOMError); 1058 if (!continueProcess) { 1059 throw new RuntimeException ( 1061 DOMMessageFormatter.formatMessage( 1062 DOMMessageFormatter.SERIALIZER_DOMAIN, 1063 "SerializationStopped", null)); 1064 } 1065 } 1066 printAttribute (name, value, attr.getSpecified(), attr); 1067 } else { 1069 printAttribute (name, value, attr.getSpecified(), attr); 1072 } 1073 } 1074 } 1076 } 1078 1079 if (elem.hasChildNodes()) { 1082 state = enterElementState( null, null, tagName, fPreserveSpace ); 1085 state.doCData = _format.isCDataElement( tagName ); 1086 state.unescaped = _format.isNonEscapingElement( tagName ); 1087 child = elem.getFirstChild(); 1088 while (child != null) { 1089 serializeNode( child ); 1090 child = child.getNextSibling(); 1091 } 1092 if (fNamespaces) { 1093 fNSBinder.popContext(); 1094 } 1095 endElementIO( null, null, tagName ); 1096 } else { 1097 if (DEBUG) { 1098 System.out.println("==>endElement: " +elem.getNodeName()); 1099 } 1100 if (fNamespaces) { 1101 fNSBinder.popContext(); 1102 } 1103 _printer.unindent(); 1104 _printer.printText( "/>" ); 1105 state.afterElement = true; 1107 state.afterComment = false; 1108 state.empty = false; 1109 if (isDocumentState()) 1110 _printer.flush(); 1111 } 1112 } 1113 1114 1115 1116 1124 1125 private void printNamespaceAttr(String prefix, String uri) throws IOException { 1126 _printer.printSpace(); 1127 if (prefix == XMLSymbols.EMPTY_STRING) { 1128 if (DEBUG) { 1129 System.out.println("=>add xmlns=\""+uri+"\" declaration"); 1130 } 1131 _printer.printText( XMLSymbols.PREFIX_XMLNS ); 1132 } else { 1133 if (DEBUG) { 1134 System.out.println("=>add xmlns:"+prefix+"=\""+uri+"\" declaration"); 1135 } 1136 _printer.printText( "xmlns:"+prefix ); 1137 } 1138 _printer.printText( "=\"" ); 1139 printEscaped( uri ); 1140 _printer.printText( '"' ); 1141 } 1142 1143 1144 1145 1154 private void printAttribute (String name, String value, boolean isSpecified, Attr attr) throws IOException { 1155 1156 if (isSpecified || (features & DOMSerializerImpl.DISCARDDEFAULT) == 0) { 1157 if (fDOMFilter !=null && 1158 (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_ATTRIBUTE)!= 0) { 1159 short code = fDOMFilter.acceptNode(attr); 1160 switch (code) { 1161 case NodeFilter.FILTER_REJECT: 1162 case NodeFilter.FILTER_SKIP: { 1163 return; 1164 } 1165 default: { 1166 } 1168 } 1169 } 1170 _printer.printSpace(); 1171 _printer.printText( name ); 1172 _printer.printText( "=\"" ); 1173 printEscaped( value ); 1174 _printer.printText( '"' ); 1175 } 1176 1177 if (name.equals( "xml:space" )) { 1181 if (value.equals( "preserve" )) 1182 fPreserveSpace = true; 1183 else 1184 fPreserveSpace = _format.getPreserveSpace(); 1185 } 1186 } 1187 1188 protected String getEntityRef( int ch ) { 1189 switch (ch) { 1192 case '<': 1193 return "lt"; 1194 case '>': 1195 return "gt"; 1196 case '"': 1197 return "quot"; 1198 case '\'': 1199 return "apos"; 1200 case '&': 1201 return "amp"; 1202 } 1203 return null; 1204 } 1205 1206 1207 1210 private Attributes extractNamespaces( Attributes attrs ) 1211 throws SAXException 1212 { 1213 AttributesImpl attrsOnly; 1214 String rawName; 1215 int i; 1216 int indexColon; 1217 String prefix; 1218 int length; 1219 1220 if (attrs == null) { 1221 return null; 1222 } 1223 length = attrs.getLength(); 1224 attrsOnly = new AttributesImpl ( attrs ); 1225 1226 for (i = length - 1 ; i >= 0 ; --i) { 1227 rawName = attrsOnly.getQName( i ); 1228 1229 if (rawName.startsWith( "xmlns" )) { 1233 if (rawName.length() == 5) { 1234 startPrefixMapping( "", attrs.getValue( i ) ); 1235 attrsOnly.removeAttribute( i ); 1236 } else if (rawName.charAt(5) == ':') { 1237 startPrefixMapping(rawName.substring(6), attrs.getValue(i)); 1238 attrsOnly.removeAttribute( i ); 1239 } 1240 } 1241 } 1242 return attrsOnly; 1243 } 1244 1245 protected void printEscaped(String source) throws IOException { 1249 int length = source.length(); 1250 for (int i = 0; i < length; ++i) { 1251 int ch = source.charAt(i); 1252 if (!XMLChar.isValid(ch)) { 1253 if (++i < length) { 1254 surrogates(ch, source.charAt(i)); 1255 } else { 1256 fatalError("The character '" + (char) ch + "' is an invalid XML character"); 1257 } 1258 continue; 1259 } 1260 if (ch == '\n' || ch == '\r' || ch == '\t') { 1262 printHex(ch); 1263 } else if (ch == '<') { 1264 _printer.printText("<"); 1265 } else if (ch == '&') { 1266 _printer.printText("&"); 1267 } else if (ch == '"') { 1268 _printer.printText("""); 1269 } else if ((ch >= ' ' && _encodingInfo.isPrintable((char) ch))) { 1270 _printer.printText((char) ch); 1271 } else { 1272 printHex(ch); 1273 } 1274 } 1275 } 1276 1277 1278 protected void printXMLChar( int ch) throws IOException { 1279 if (ch == '\r') { 1280 printHex(ch); 1281 } else if ( ch == '<') { 1282 _printer.printText("<"); 1283 } else if (ch == '&') { 1284 _printer.printText("&"); 1285 } else if (ch == '>'){ 1286 _printer.printText(">"); 1289 } else if ( ch == '\n' || ch == '\t' || 1290 ( ch >= ' ' && _encodingInfo.isPrintable((char)ch))) { 1291 _printer.printText((char)ch); 1292 } else { 1293 printHex(ch); 1294 } 1295 } 1296 1297 protected void printText( String text, boolean preserveSpace, boolean unescaped ) 1298 throws IOException { 1299 int index; 1300 char ch; 1301 int length = text.length(); 1302 if ( preserveSpace ) { 1303 for ( index = 0 ; index < length ; ++index ) { 1308 ch = text.charAt( index ); 1309 if (!XMLChar.isValid(ch)) { 1310 if (++index <length) { 1312 surrogates(ch, text.charAt(index)); 1313 } else { 1314 fatalError("The character '"+(char)ch+"' is an invalid XML character"); 1315 } 1316 continue; 1317 } 1318 if ( unescaped ) { 1319 _printer.printText( ch ); 1320 } else 1321 printXMLChar( ch ); 1322 } 1323 } else { 1324 for ( index = 0 ; index < length ; ++index ) { 1330 ch = text.charAt( index ); 1331 if (!XMLChar.isValid(ch)) { 1332 if (++index <length) { 1334 surrogates(ch, text.charAt(index)); 1335 } else { 1336 fatalError("The character '"+(char)ch+"' is an invalid XML character"); 1337 } 1338 continue; 1339 } 1340 1341 if ( unescaped ) 1342 _printer.printText( ch ); 1343 else 1344 printXMLChar( ch); 1345 } 1346 } 1347 } 1348 1349 1350 1351 protected void printText( char[] chars, int start, int length, 1352 boolean preserveSpace, boolean unescaped ) throws IOException { 1353 int index; 1354 char ch; 1355 1356 if ( preserveSpace ) { 1357 while ( length-- > 0 ) { 1362 ch = chars[ start ]; 1363 ++start; 1364 if (!XMLChar.isValid(ch)) { 1365 if (++start <length) { 1367 surrogates(ch, chars[start]); 1368 } else { 1369 fatalError("The character '"+(char)ch+"' is an invalid XML character"); 1370 } 1371 continue; 1372 } 1373 if ( unescaped ) 1374 _printer.printText( ch ); 1375 else 1376 printXMLChar( ch ); 1377 } 1378 } else { 1379 while ( length-- > 0 ) { 1385 ch = chars[ start ]; 1386 ++start; 1387 1388 if (!XMLChar.isValid(ch)) { 1389 if (++start <length) { 1391 surrogates(ch, chars[start]); 1392 } else { 1393 fatalError("The character '"+(char)ch+"' is an invalid XML character"); 1394 } 1395 continue; 1396 } 1397 if ( unescaped ) 1398 _printer.printText( ch ); 1399 else 1400 printXMLChar( ch ); 1401 } 1402 } 1403 } 1404 1405 1406 1412 protected void checkUnboundNamespacePrefixedNode (Node node) throws IOException { 1413 1414 if (fNamespaces) { 1415 1416 if (DEBUG) { 1417 System.out.println("==>serializeNode("+node.getNodeName()+") [Entity Reference - Namespaces on]"); 1418 System.out.println("==>Declared Prefix Count: " + fNSBinder.getDeclaredPrefixCount()); 1419 System.out.println("==>Node Name: " + node.getNodeName()); 1420 System.out.println("==>First Child Node Name: " + node.getFirstChild().getNodeName()); 1421 System.out.println("==>First Child Node Prefix: " + node.getFirstChild().getPrefix()); 1422 System.out.println("==>First Child Node NamespaceURI: " + node.getFirstChild().getNamespaceURI()); 1423 } 1424 1425 1426 Node child, next; 1427 for (child = node.getFirstChild(); child != null; child = next) { 1428 next = child.getNextSibling(); 1429 if (DEBUG) { 1430 System.out.println("==>serializeNode("+child.getNodeName()+") [Child Node]"); 1431 System.out.println("==>serializeNode("+child.getPrefix()+") [Child Node Prefix]"); 1432 } 1433 1434 String prefix = child.getPrefix(); 1437 if (fNSBinder.getURI(prefix) == null && prefix != null) { 1438 fatalError("The replacement text of the entity node '" 1439 + node.getNodeName() 1440 + "' contains an element node '" 1441 + child.getNodeName() 1442 + "' with an undeclared prefix '" 1443 + prefix + "'."); 1444 } 1445 1446 if (child.getNodeType() == Node.ELEMENT_NODE) { 1447 1448 NamedNodeMap attrs = child.getAttributes(); 1449 1450 for (int i = 0; i< attrs.getLength(); i++ ) { 1451 1452 String attrPrefix = attrs.item(i).getPrefix(); 1453 if (fNSBinder.getURI(attrPrefix) == null && attrPrefix != null) { 1454 fatalError("The replacement text of the entity node '" 1455 + node.getNodeName() 1456 + "' contains an element node '" 1457 + child.getNodeName() 1458 + "' with an attribute '" 1459 + attrs.item(i).getNodeName() 1460 + "' an undeclared prefix '" 1461 + attrPrefix + "'."); 1462 } 1463 1464 } 1465 1466 } 1467 1468 if (child.hasChildNodes()) { 1469 checkUnboundNamespacePrefixedNode(child); 1470 } 1471 } 1472 } 1473 } 1474 1475 public boolean reset() { 1476 super.reset(); 1477 if (fNSBinder != null){ 1478 fNSBinder.reset(); 1479 fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); 1482 } 1483 return true; 1484 } 1485 1486} 1487 1488 1489 1490 1491 | Popular Tags |