KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xml > serialize > XMLSerializer


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58
59
60 // Sep 14, 2000:
61
// Fixed problem with namespace handling. Contributed by
62
// David Blondeau <blondeau@intalio.com>
63
// Sep 14, 2000:
64
// Fixed serializer to report IO exception directly, instead at
65
// the end of document processing.
66
// Reported by Patrick Higgins <phiggins@transzap.com>
67
// Aug 21, 2000:
68
// Fixed bug in startDocument not calling prepare.
69
// Reported by Mikael Staldal <d96-mst-ingen-reklam@d.kth.se>
70
// Aug 21, 2000:
71
// Added ability to omit DOCTYPE declaration.
72

73
74 package org.enhydra.apache.xml.serialize;
75
76
77 import java.io.IOException JavaDoc;
78 import java.io.OutputStream JavaDoc;
79 import java.io.Writer JavaDoc;
80 import java.util.Enumeration JavaDoc;
81
82 import org.w3c.dom.Attr JavaDoc;
83 import org.w3c.dom.Element JavaDoc;
84 import org.w3c.dom.NamedNodeMap JavaDoc;
85 import org.w3c.dom.Node JavaDoc;
86 import org.xml.sax.AttributeList JavaDoc;
87 import org.xml.sax.Attributes JavaDoc;
88 import org.xml.sax.SAXException JavaDoc;
89 import org.xml.sax.helpers.AttributesImpl JavaDoc;
90
91
92 /**
93  * Implements an XML serializer supporting both DOM and SAX pretty
94  * serializing. For usage instructions see {@link Serializer}.
95  * <p>
96  * If an output stream is used, the encoding is taken from the
97  * output format (defaults to <tt>UTF-8</tt>). If a writer is
98  * used, make sure the writer uses the same encoding (if applies)
99  * as specified in the output format.
100  * <p>
101  * The serializer supports both DOM and SAX. DOM serializing is done
102  * by calling {@link #serialize} and SAX serializing is done by firing
103  * SAX events and using the serializer as a document handler.
104  * <p>
105  * If an I/O exception occurs while serializing, the serializer
106  * will not throw an exception directly, but only throw it
107  * at the end of serializing (either DOM or SAX's {@link
108  * org.xml.sax.DocumentHandler#endDocument}.
109  * <p>
110  * For elements that are not specified as whitespace preserving,
111  * the serializer will potentially break long text lines at space
112  * boundaries, indent lines, and serialize elements on separate
113  * lines. Line terminators will be regarded as spaces, and
114  * spaces at beginning of line will be stripped.
115  *
116  *
117  * @version $Revision: 1.2 $ $Date: 2005/01/26 08:28:45 $
118  * @author <a HREF="mailto:arkin@intalio.com">Assaf Arkin</a>
119  * @see Serializer
120  */

121 public class XMLSerializer
122     extends BaseMarkupSerializer
123 {
124
125
126     /**
127      * Constructs a new serializer. The serializer cannot be used without
128      * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
129      * first.
130      */

131     public XMLSerializer()
132     {
133         super( new OutputFormat( Method.XML, null, false ) );
134     }
135
136
137     /**
138      * Constructs a new serializer. The serializer cannot be used without
139      * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
140      * first.
141      */

142     public XMLSerializer( OutputFormat format )
143     {
144         super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
145         _format.setMethod( Method.XML );
146     }
147
148
149     /**
150      * Constructs a new serializer that writes to the specified writer
151      * using the specified output format. If <tt>format</tt> is null,
152      * will use a default output format.
153      *
154      * @param writer The writer to use
155      * @param format The output format to use, null for the default
156      */

157     public XMLSerializer( Writer JavaDoc writer, OutputFormat format )
158     {
159         super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
160         _format.setMethod( Method.XML );
161         setOutputCharStream( writer );
162     }
163
164
165     /**
166      * Constructs a new serializer that writes to the specified output
167      * stream using the specified output format. If <tt>format</tt>
168      * is null, will use a default output format.
169      *
170      * @param output The output stream to use
171      * @param format The output format to use, null for the default
172      */

173     public XMLSerializer( OutputStream JavaDoc output, OutputFormat format )
174     {
175         super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
176         _format.setMethod( Method.XML );
177         setOutputByteStream( output );
178     }
179
180
181     public void setOutputFormat( OutputFormat format )
182     {
183         super.setOutputFormat( format != null ? format : new OutputFormat( Method.XML, null, false ) );
184     }
185
186
187     //-----------------------------------------//
188
// SAX content handler serializing methods //
189
//-----------------------------------------//
190

191
192     public void startElement( String JavaDoc namespaceURI, String JavaDoc localName,
193                               String JavaDoc rawName, Attributes JavaDoc attrs )
194         throws SAXException JavaDoc
195     {
196         int i;
197         boolean preserveSpace;
198         ElementState state;
199         String JavaDoc name;
200         String JavaDoc value;
201         boolean addNSAttr = false;
202
203         try {
204         if ( _printer == null )
205             throw new IllegalStateException JavaDoc( "SER002 No writer supplied for serializer" );
206
207         state = getElementState();
208         if ( isDocumentState() ) {
209             // If this is the root element handle it differently.
210
// If the first root element in the document, serialize
211
// the document's DOCTYPE. Space preserving defaults
212
// to that of the output format.
213
if ( ! _started )
214                     startDocument( ( localName == null || localName.length() == 0 ) ? rawName : localName );
215         } else {
216             // For any other element, if first in parent, then
217
// close parent's opening tag and use the parnet's
218
// space preserving.
219
if ( state.empty )
220                 _printer.printText( '>' );
221             // Must leave CData section first
222
if ( state.inCData )
223             {
224                 _printer.printText( "]]>" );
225                 state.inCData = false;
226             }
227             // Indent this element on a new line if the first
228
// content of the parent element or immediately
229
// following an element or a comment
230
if ( _indenting && ! state.preserveSpace &&
231                  ( state.empty || state.afterElement || state.afterComment) )
232                 _printer.breakLine();
233         }
234         preserveSpace = state.preserveSpace;
235
236             //We remove the namespaces from the attributes list so that they will
237
//be in _prefixes
238
attrs = extractNamespaces(attrs);
239
240         // Do not change the current element state yet.
241
// This only happens in endElement().
242
if ( rawName == null || rawName.length() == 0 ) {
243                 if ( localName == null )
244                     throw new SAXException JavaDoc( "No rawName and localName is null" );
245                 if ( namespaceURI != null && ! namespaceURI.equals( "" ) ) {
246                 String JavaDoc prefix;
247                 prefix = getPrefix( namespaceURI );
248                     if ( prefix != null && prefix.length() > 0 )
249                     rawName = prefix + ":" + localName;
250                     else
251                         rawName = localName;
252                 } else
253                     rawName = localName;
254             addNSAttr = true;
255         }
256
257         _printer.printText( '<' );
258         _printer.printText( rawName );
259         _printer.indent();
260
261         // For each attribute print it's name and value as one part,
262
// separated with a space so the element can be broken on
263
// multiple lines.
264
if ( attrs != null ) {
265             for ( i = 0 ; i < attrs.getLength() ; ++i ) {
266                 _printer.printSpace();
267
268                 name = attrs.getQName( i );
269                     if ( name != null && name.length() == 0 ) {
270                     String JavaDoc prefix;
271                     String JavaDoc attrURI;
272
273                     name = attrs.getLocalName( i );
274                     attrURI = attrs.getURI( i );
275                         if ( ( attrURI != null && attrURI.length() != 0 ) &&
276                              ( namespaceURI == null || namespaceURI.length() == 0 ||
277                                               ! attrURI.equals( namespaceURI ) ) ) {
278                         prefix = getPrefix( attrURI );
279                         if ( prefix != null && prefix.length() > 0 )
280                             name = prefix + ":" + name;
281                     }
282                 }
283
284                 value = attrs.getValue( i );
285                 if ( value == null )
286                     value = "";
287                 _printer.printText( name );
288                 _printer.printText( "=\"" );
289                 printEscaped( value );
290                 _printer.printText( '"' );
291
292                 // If the attribute xml:space exists, determine whether
293
// to preserve spaces in this and child nodes based on
294
// its value.
295
if ( name.equals( "xml:space" ) ) {
296                     if ( value.equals( "preserve" ) )
297                         preserveSpace = true;
298                     else
299                         preserveSpace = _format.getPreserveSpace();
300                 }
301             }
302         }
303
304             if ( _prefixes != null ) {
305             Enumeration JavaDoc enumer;
306
307             enumer = _prefixes.keys();
308             while ( enumer.hasMoreElements() ) {
309                 _printer.printSpace();
310                 value = (String JavaDoc) enumer.nextElement();
311                 name = (String JavaDoc) _prefixes.get( value );
312                 if ( name.length() == 0 ) {
313                     _printer.printText( "xmlns=\"" );
314                     printEscaped( value );
315                     _printer.printText( '"' );
316                 } else {
317                     _printer.printText( "xmlns:" );
318                     _printer.printText( name );
319                     _printer.printText( "=\"" );
320                     printEscaped( value );
321                     _printer.printText( '"' );
322                 }
323             }
324         }
325
326         // Now it's time to enter a new element state
327
// with the tag name and space preserving.
328
// We still do not change the curent element state.
329
state = enterElementState( namespaceURI, localName, rawName, preserveSpace );
330             name = ( localName == null || localName.length() == 0 ) ? rawName : namespaceURI + "^" + localName;
331             state.doCData = _format.isCDataElement( name );
332             state.unescaped = _format.isNonEscapingElement( name );
333         } catch ( IOException JavaDoc except ) {
334             throw new SAXException JavaDoc( except );
335         }
336     }
337
338
339     public void endElement( String JavaDoc namespaceURI, String JavaDoc localName,
340                             String JavaDoc rawName )
341         throws SAXException JavaDoc
342     {
343         try {
344             endElementIO( namespaceURI, localName, rawName );
345         } catch ( IOException JavaDoc except ) {
346             throw new SAXException JavaDoc( except );
347         }
348     }
349
350
351     public void endElementIO( String JavaDoc namespaceURI, String JavaDoc localName,
352                             String JavaDoc rawName )
353         throws IOException JavaDoc
354     {
355         ElementState state;
356
357         // Works much like content() with additions for closing
358
// an element. Note the different checks for the closed
359
// element's state and the parent element's state.
360
_printer.unindent();
361         state = getElementState();
362         if ( state.empty ) {
363             _printer.printText( "/>" );
364         } else {
365             // Must leave CData section first
366
if ( state.inCData )
367                 _printer.printText( "]]>" );
368             // This element is not empty and that last content was
369
// another element, so print a line break before that
370
// last element and this element's closing tag.
371
if ( _indenting && ! state.preserveSpace && (state.afterElement || state.afterComment) )
372                 _printer.breakLine();
373             _printer.printText( "</" );
374             _printer.printText( state.rawName );
375             _printer.printText( '>' );
376         }
377         // Leave the element state and update that of the parent
378
// (if we're not root) to not empty and after element.
379
state = leaveElementState();
380         state.afterElement = true;
381         state.afterComment = false;
382         state.empty = false;
383         if ( isDocumentState() )
384             _printer.flush();
385     }
386
387
388     //------------------------------------------//
389
// SAX document handler serializing methods //
390
//------------------------------------------//
391

392
393     public void startElement( String JavaDoc tagName, AttributeList JavaDoc attrs )
394         throws SAXException JavaDoc
395     {
396         int i;
397         boolean preserveSpace;
398         ElementState state;
399         String JavaDoc name;
400         String JavaDoc value;
401
402         try {
403         if ( _printer == null )
404             throw new IllegalStateException JavaDoc( "SER002 No writer supplied for serializer" );
405
406         state = getElementState();
407         if ( isDocumentState() ) {
408             // If this is the root element handle it differently.
409
// If the first root element in the document, serialize
410
// the document's DOCTYPE. Space preserving defaults
411
// to that of the output format.
412
if ( ! _started )
413                 startDocument( tagName );
414         } else {
415             // For any other element, if first in parent, then
416
// close parent's opening tag and use the parnet's
417
// space preserving.
418
if ( state.empty )
419                 _printer.printText( '>' );
420             // Must leave CData section first
421
if ( state.inCData )
422             {
423                 _printer.printText( "]]>" );
424                 state.inCData = false;
425             }
426             // Indent this element on a new line if the first
427
// content of the parent element or immediately
428
// following an element.
429
if ( _indenting && ! state.preserveSpace &&
430                  ( state.empty || state.afterElement || state.afterComment) )
431                 _printer.breakLine();
432         }
433         preserveSpace = state.preserveSpace;
434
435         // Do not change the current element state yet.
436
// This only happens in endElement().
437

438         _printer.printText( '<' );
439         _printer.printText( tagName );
440         _printer.indent();
441
442         // For each attribute print it's name and value as one part,
443
// separated with a space so the element can be broken on
444
// multiple lines.
445
if ( attrs != null ) {
446             for ( i = 0 ; i < attrs.getLength() ; ++i ) {
447                 _printer.printSpace();
448                 name = attrs.getName( i );
449                 value = attrs.getValue( i );
450                 if ( value != null ) {
451                     _printer.printText( name );
452                     _printer.printText( "=\"" );
453                     printEscaped( value );
454                     _printer.printText( '"' );
455                 }
456
457                 // If the attribute xml:space exists, determine whether
458
// to preserve spaces in this and child nodes based on
459
// its value.
460
if ( name.equals( "xml:space" ) ) {
461                     if ( value.equals( "preserve" ) )
462                         preserveSpace = true;
463                     else
464                         preserveSpace = _format.getPreserveSpace();
465                 }
466             }
467         }
468         // Now it's time to enter a new element state
469
// with the tag name and space preserving.
470
// We still do not change the curent element state.
471
state = enterElementState( null, null, tagName, preserveSpace );
472         state.doCData = _format.isCDataElement( tagName );
473         state.unescaped = _format.isNonEscapingElement( tagName );
474         } catch ( IOException JavaDoc except ) {
475             throw new SAXException JavaDoc( except );
476     }
477
478     }
479
480
481     public void endElement( String JavaDoc tagName )
482         throws SAXException JavaDoc
483     {
484         endElement( null, null, tagName );
485     }
486
487
488
489     //------------------------------------------//
490
// Generic node serializing methods methods //
491
//------------------------------------------//
492

493
494     /**
495      * Called to serialize the document's DOCTYPE by the root element.
496      * The document type declaration must name the root element,
497      * but the root element is only known when that element is serialized,
498      * and not at the start of the document.
499      * <p>
500      * This method will check if it has not been called before ({@link #_started}),
501      * will serialize the document type declaration, and will serialize all
502      * pre-root comments and PIs that were accumulated in the document
503      * (see {@link #serializePreRoot}). Pre-root will be serialized even if
504      * this is not the first root element of the document.
505      */

506     protected void startDocument( String JavaDoc rootTagName )
507         throws IOException JavaDoc
508     {
509         int i;
510         String JavaDoc dtd;
511
512         dtd = _printer.leaveDTD();
513         if ( ! _started ) {
514
515             if ( ! _format.getOmitXMLDeclaration() ) {
516                 StringBuffer JavaDoc buffer;
517
518                 // Serialize the document declaration appreaing at the head
519
// of very XML document (unless asked not to).
520
buffer = new StringBuffer JavaDoc( "<?xml version=\"" );
521                 if ( _format.getVersion() != null )
522                     buffer.append( _format.getVersion() );
523                 else
524                     buffer.append( "1.0" );
525                 buffer.append( '"' );
526                 if ( _format.getEncoding() != null ) {
527                     buffer.append( " encoding=\"" );
528                     buffer.append( _format.getEncoding() );
529                     buffer.append( '"' );
530                 }
531                 if ( _format.getStandalone() && _docTypeSystemId == null &&
532                      _docTypePublicId == null )
533                     buffer.append( " standalone=\"yes\"" );
534                 buffer.append( "?>" );
535                 _printer.printText( buffer );
536                 _printer.breakLine();
537             }
538
539             if ( ! _format.getOmitDocumentType() ) {
540                 if ( _docTypeSystemId != null ) {
541                     // System identifier must be specified to print DOCTYPE.
542
// If public identifier is specified print 'PUBLIC
543
// <public> <system>', if not, print 'SYSTEM <system>'.
544
_printer.printText( "<!DOCTYPE " );
545                     _printer.printText( rootTagName );
546                     if ( _docTypePublicId != null ) {
547                         _printer.printText( " PUBLIC " );
548                         printDoctypeURL( _docTypePublicId );
549                         if ( _indenting ) {
550                             _printer.breakLine();
551                             for ( i = 0 ; i < 18 + rootTagName.length() ; ++i )
552                                 _printer.printText( " " );
553                         } else
554                             _printer.printText( " " );
555                     printDoctypeURL( _docTypeSystemId );
556                     }
557                     else {
558                         _printer.printText( " SYSTEM " );
559                         printDoctypeURL( _docTypeSystemId );
560                     }
561
562                     // If we accumulated any DTD contents while printing.
563
// this would be the place to print it.
564
if ( dtd != null && dtd.length() > 0 ) {
565                         _printer.printText( " [" );
566                         printText( dtd, true, true );
567                         _printer.printText( ']' );
568                     }
569
570                     _printer.printText( ">" );
571                     _printer.breakLine();
572                 } else if ( dtd != null && dtd.length() > 0 ) {
573                     _printer.printText( "<!DOCTYPE " );
574                     _printer.printText( rootTagName );
575                     _printer.printText( " [" );
576                     printText( dtd, true, true );
577                     _printer.printText( "]>" );
578                     _printer.breakLine();
579                 }
580             }
581         }
582         _started = true;
583         // Always serialize these, even if not te first root element.
584
serializePreRoot();
585     }
586
587
588     /**
589      * Called to serialize a DOM element. Equivalent to calling {@link
590      * #startElement}, {@link #endElement} and serializing everything
591      * inbetween, but better optimized.
592      */

593     protected void serializeElement( Element JavaDoc elem )
594         throws IOException JavaDoc
595     {
596         Attr JavaDoc attr;
597         NamedNodeMap JavaDoc attrMap;
598         int i;
599         Node JavaDoc child;
600         ElementState state;
601         boolean preserveSpace;
602         String JavaDoc name;
603         String JavaDoc value;
604         String JavaDoc tagName;
605
606         tagName = elem.getTagName();
607         state = getElementState();
608         if ( isDocumentState() ) {
609             // If this is the root element handle it differently.
610
// If the first root element in the document, serialize
611
// the document's DOCTYPE. Space preserving defaults
612
// to that of the output format.
613
if ( ! _started )
614                 startDocument( tagName );
615         } else {
616             // For any other element, if first in parent, then
617
// close parent's opening tag and use the parnet's
618
// space preserving.
619
if ( state.empty )
620                 _printer.printText( '>' );
621             // Must leave CData section first
622
if ( state.inCData )
623             {
624                 _printer.printText( "]]>" );
625                 state.inCData = false;
626             }
627             // Indent this element on a new line if the first
628
// content of the parent element or immediately
629
// following an element.
630
if ( _indenting && ! state.preserveSpace &&
631                  ( state.empty || state.afterElement || state.afterComment) )
632                 _printer.breakLine();
633         }
634         preserveSpace = state.preserveSpace;
635
636         // Do not change the current element state yet.
637
// This only happens in endElement().
638

639         _printer.printText( '<' );
640         _printer.printText( tagName );
641         _printer.indent();
642
643         // Lookup the element's attribute, but only print specified
644
// attributes. (Unspecified attributes are derived from the DTD.
645
// For each attribute print it's name and value as one part,
646
// separated with a space so the element can be broken on
647
// multiple lines.
648
attrMap = elem.getAttributes();
649         if ( attrMap != null ) {
650             for ( i = 0 ; i < attrMap.getLength() ; ++i ) {
651                 attr = (Attr JavaDoc) attrMap.item( i );
652                 name = attr.getName();
653                 value = attr.getValue();
654                 if ( value == null )
655                     value = "";
656                 if ( attr.getSpecified() ) {
657                     _printer.printSpace();
658                     _printer.printText( name );
659                     _printer.printText( "=\"" );
660                     printEscaped( value );
661                     _printer.printText( '"' );
662                 }
663                 // If the attribute xml:space exists, determine whether
664
// to preserve spaces in this and child nodes based on
665
// its value.
666
if ( name.equals( "xml:space" ) ) {
667                     if ( value.equals( "preserve" ) )
668                         preserveSpace = true;
669                     else
670                         preserveSpace = _format.getPreserveSpace();
671                 }
672             }
673         }
674
675         // If element has children, then serialize them, otherwise
676
// serialize en empty tag.
677
if ( elem.hasChildNodes() ) {
678             // Enter an element state, and serialize the children
679
// one by one. Finally, end the element.
680
state = enterElementState( null, null, tagName, preserveSpace );
681             state.doCData = _format.isCDataElement( tagName );
682             state.unescaped = _format.isNonEscapingElement( tagName );
683             child = elem.getFirstChild();
684             while ( child != null ) {
685                 serializeNode( child );
686                 child = child.getNextSibling();
687             }
688             endElementIO( null, null, tagName );
689         } else {
690             _printer.unindent();
691             _printer.printText( "/>" );
692             // After element but parent element is no longer empty.
693
state.afterElement = true;
694             state.afterComment = false;
695             state.empty = false;
696             if ( isDocumentState() )
697                 _printer.flush();
698         }
699     }
700
701
702     protected String JavaDoc getEntityRef( int ch )
703     {
704         // Encode special XML characters into the equivalent character references.
705
// These five are defined by default for all XML documents.
706
switch ( ch ) {
707         case '<':
708             return "lt";
709         case '>':
710             return "gt";
711         case '"':
712             return "quot";
713         case '\'':
714             return "apos";
715         case '&':
716             return "amp";
717         }
718         return null;
719     }
720
721
722     /** Retrieve and remove the namespaces declarations from the list of attributes.
723      *
724      */

725     private Attributes JavaDoc extractNamespaces( Attributes JavaDoc attrs )
726         throws SAXException JavaDoc
727     {
728         AttributesImpl JavaDoc attrsOnly;
729         String JavaDoc rawName;
730         int i;
731         int indexColon;
732         String JavaDoc prefix;
733         int length;
734
735         length = attrs.getLength();
736         attrsOnly = new AttributesImpl JavaDoc( attrs );
737
738         for ( i = length - 1 ; i >= 0 ; --i ) {
739             rawName = attrsOnly.getQName( i );
740
741             //We have to exclude the namespaces declarations from the attributes
742
//Append only when the feature http://xml.org/sax/features/namespace-prefixes"
743
//is TRUE
744
if ( rawName.startsWith( "xmlns" ) ) {
745                 if (rawName.length() == 5) {
746                     startPrefixMapping( "", attrs.getValue( i ) );
747                     attrsOnly.removeAttribute( i );
748                 } else if (rawName.charAt(5) == ':') {
749                     startPrefixMapping(rawName.substring(6), attrs.getValue(i));
750                     attrsOnly.removeAttribute( i );
751                 }
752             }
753         }
754         return attrsOnly;
755     }
756 }
757
758
759
Popular Tags