You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by el...@apache.org on 2002/01/12 01:10:52 UTC

cvs commit: xml-xerces/java/src/org/apache/xml/serialize BaseMarkupSerializer.java XMLSerializer.java

elena       02/01/11 16:10:52

  Modified:    java/src/org/apache/xerces/util NamespaceSupport.java
               java/src/org/apache/xml/serialize BaseMarkupSerializer.java
                        XMLSerializer.java
  Log:
  Implemented namespace fixup during serialization of DOM tree.
  
  Revision  Changes    Path
  1.6       +33 -1     xml-xerces/java/src/org/apache/xerces/util/NamespaceSupport.java
  
  Index: NamespaceSupport.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/util/NamespaceSupport.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- NamespaceSupport.java	10 Jan 2002 06:34:23 -0000	1.5
  +++ NamespaceSupport.java	12 Jan 2002 00:10:51 -0000	1.6
  @@ -67,7 +67,7 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: NamespaceSupport.java,v 1.5 2002/01/10 06:34:23 twl Exp $
  + * @version $Id: NamespaceSupport.java,v 1.6 2002/01/12 00:10:51 elena Exp $
    */
   public class NamespaceSupport 
       implements NamespaceContext {
  @@ -273,6 +273,7 @@
           // bind prefix to uri in current context
           fNamespace[fNamespaceSize++] = prefix;
           fNamespace[fNamespaceSize++] = uri;
  +
           return true;
   
       } // declarePrefix(String,String):boolean
  @@ -304,6 +305,36 @@
   
       } // getURI(String):String
   
  +
  +
  +    /**
  +     * Look up a namespace URI and get one of the mapped prefix.
  +     * <p>
  +     * This method looks up the namespace URI in the current context.
  +     *
  +     * @param uri The namespace URI to look up.
  +     *
  +     * @return one of the associated prefixes, or null if the uri
  +     *         does not map to any prefix.
  +     *
  +     * @see #getPrefix
  +     * @see #getPrefixes
  +     */
  +    public String getPrefix(String uri) {
  +
  +        // find uri in current context
  +        for (int i = fNamespaceSize; i > 0; i -= 2) {
  +            if (fNamespace[i - 1] == uri) {
  +                return fNamespace[i - 2];
  +            }
  +        }
  +
  +        // uri not found
  +        return null;
  +
  +    } // getURI(String):String
  +
  +
       /**
        * Return a count of all prefixes currently declared, including
        * the default prefix if bound.
  @@ -442,5 +473,6 @@
           } // getParentContext():NamespaceContext
   
       } // class Context
  +
   
   } // class NamespaceSupport
  
  
  
  1.31      +24 -11    xml-xerces/java/src/org/apache/xml/serialize/BaseMarkupSerializer.java
  
  Index: BaseMarkupSerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xml/serialize/BaseMarkupSerializer.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- BaseMarkupSerializer.java	3 Dec 2001 21:13:09 -0000	1.30
  +++ BaseMarkupSerializer.java	12 Jan 2002 00:10:52 -0000	1.31
  @@ -149,7 +149,7 @@
    * another element.
    *
    *
  - * @version $Revision: 1.30 $ $Date: 2001/12/03 21:13:09 $
  + * @version $Revision: 1.31 $ $Date: 2002/01/12 00:10:52 $
    * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
    * @author <a href="mailto:rahul.srivastava@sun.com">Rahul Srivastava</a>
    * @author Elena Litani, IBM 
  @@ -417,6 +417,7 @@
       public void serialize( Element elem )
           throws IOException
       {
  +        reset();
           prepare();
           serializeNode( elem );
           _printer.flush();
  @@ -437,6 +438,7 @@
       public void serialize( DocumentFragment frag )
           throws IOException
       {
  +        reset();
           prepare();
           serializeNode( frag );
           _printer.flush();
  @@ -457,6 +459,7 @@
       public void serialize( Document doc )
           throws IOException
       {
  +        reset();
           prepare();
           serializeNode( doc );
           serializePreRoot();
  @@ -1211,11 +1214,8 @@
               if (index >=0 && !((Boolean)fFeatures.get("split-cdata-sections")).booleanValue()) {
                  // issue fatal error
                   if (fDOMErrorHandler != null) {
  -                    fDOMError.reset();
  -                    fDOMError.setMessage("The character sequence \"]]>\" must not appear in content"+
  -                                         " unless used to mark the end of a CDATA section.");
  -                    fDOMError.setSeverity(DOMError.SEVERITY_FATAL_ERROR);
  -                    fDOMError.setLocator(new DOMLocatorImpl(-1, -1, -1, fCurrentNode, null));
  +                    modifyDOMError("The character sequence \"]]>\" must not appear in content"+
  +                                   " unless used to mark the end of a CDATA section.", DOMError.SEVERITY_FATAL_ERROR);
                       boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
                       // Should we always terminate the serialization?
                       // otherwise should we split CDATA section..?
  @@ -1227,11 +1227,9 @@
               else if (index >=0 && ((Boolean)fFeatures.get("split-cdata-sections")).booleanValue()) {
                  // issue warning
                  if (fDOMErrorHandler != null) {
  -                    fDOMError.reset();
  -                    fDOMError.setMessage("Spliting a CDATA section containing the CDATA section termination marker ']]>' ");
  -                    fDOMError.setSeverity(DOMError.SEVERITY_WARNING);
  -                    fDOMError.setLocator(new DOMLocatorImpl(-1, -1, -1, fCurrentNode, null));
  -                    fDOMErrorHandler.handleError(fDOMError);
  +                   modifyDOMError("Spliting a CDATA section containing the CDATA section termination marker ']]>' ", 
  +                                  DOMError.SEVERITY_WARNING);
  +                   fDOMErrorHandler.handleError(fDOMError);
                   }
               }
   
  @@ -1618,5 +1616,20 @@
           return null;
       }
   
  +    /**
  +     * The method modifies global DOM error object
  +     * 
  +     * @param message
  +     * @param severity
  +     * @return 
  +     */
  +    protected DOMError modifyDOMError(String message, short severity){
  +            fDOMError.reset();
  +            fDOMError.setMessage(message);
  +            fDOMError.setSeverity(severity);
  +            fDOMError.setLocator(new DOMLocatorImpl(-1, -1, -1, fCurrentNode, null));
  +            return fDOMError;
  +        
  +    }
   
   }
  
  
  
  1.27      +664 -285  xml-xerces/java/src/org/apache/xml/serialize/XMLSerializer.java
  
  Index: XMLSerializer.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xml/serialize/XMLSerializer.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- XMLSerializer.java	3 Dec 2001 21:13:09 -0000	1.26
  +++ XMLSerializer.java	12 Jan 2002 00:10:52 -0000	1.27
  @@ -90,8 +90,13 @@
   import org.xml.sax.SAXException;
   import org.xml.sax.helpers.AttributesImpl;
   
  +import org.apache.xerces.dom3.DOMErrorHandler;
  +import org.apache.xerces.dom3.DOMError;
   import org.apache.xerces.dom3.ls.DOMWriter;
   import org.apache.xerces.dom3.DOMErrorHandler;
  +import org.apache.xerces.util.SymbolTable;
  +import org.apache.xerces.util.NamespaceSupport;
  +import org.apache.xerces.xni.NamespaceContext;
   
   /**
    * Implements an XML serializer supporting both DOM and SAX pretty
  @@ -118,16 +123,45 @@
    * spaces at beginning of line will be stripped.
    *
    *
  - * @version $Revision: 1.26 $ $Date: 2001/12/03 21:13:09 $
  + * @version $Revision: 1.27 $ $Date: 2002/01/12 00:10:52 $
    * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
    * @author <a href="mailto:rahul.srivastava@sun.com">Rahul Srivastava</a>
  + * @author Elena Litani, IBM
    * @see Serializer
    */
   public class XMLSerializer
  -    extends BaseMarkupSerializer
  -    implements DOMWriter 
  -{
  +extends BaseMarkupSerializer
  +implements DOMWriter {
  +
  +    //
  +    // constants
  +    //
  +
  +    protected static final boolean DEBUG = false;
  +
  +    // 
  +    // data
  +    //
  +
  +    protected static final NamespaceSupport fNamespaceSupport = new NamespaceSupport();
  +    protected static final SymbolTable fSymbolTable = new SymbolTable();    
  +    protected String fEmptySymbol;
  +    protected String fXmlSymbol;
  +    protected String fXmlnsSymbol;
  +    // is node dom level 1 node?
  +    protected boolean fDOML1 = false;
  +    // serialized attributes list
  +    int[] fSerializedAttributes = new int[2];
  +    // local declarations
  +    int[] fLocalNSDecls         = new int[2];
  +    int fLocalNSCount = 0;
  +    int fSerializedCount = 0;
  +
  +    // counter for new prefix names
  +    protected int fNamespaceCounter = 1;
  +
   
  +    private boolean fPreserveSpace;
       private String fEncoding;
       private String fLastEncoding;
   
  @@ -137,8 +171,7 @@
        * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
        * first.
        */
  -    public XMLSerializer()
  -    {
  +    public XMLSerializer() {
           super( new OutputFormat( Method.XML, null, false ) );
           fFeatures = new Hashtable();
           initFeatures();
  @@ -150,8 +183,7 @@
        * calling {@link #setOutputCharStream} or {@link #setOutputByteStream}
        * first.
        */
  -    public XMLSerializer( OutputFormat format )
  -    {
  +    public XMLSerializer( OutputFormat format ) {
           super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
           _format.setMethod( Method.XML );
           fFeatures = new Hashtable();
  @@ -167,8 +199,7 @@
        * @param writer The writer to use
        * @param format The output format to use, null for the default
        */
  -    public XMLSerializer( Writer writer, OutputFormat format )
  -    {
  +    public XMLSerializer( Writer writer, OutputFormat format ) {
           super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
           _format.setMethod( Method.XML );
           setOutputCharStream( writer );
  @@ -185,8 +216,7 @@
        * @param output The output stream to use
        * @param format The output format to use, null for the default
        */
  -    public XMLSerializer( OutputStream output, OutputFormat format )
  -    {
  +    public XMLSerializer( OutputStream output, OutputFormat format ) {
           super( format != null ? format : new OutputFormat( Method.XML, null, false ) );
           _format.setMethod( Method.XML );
           setOutputByteStream( output );
  @@ -195,8 +225,7 @@
       }
   
   
  -    public void setOutputFormat( OutputFormat format )
  -    {
  +    public void setOutputFormat( OutputFormat format ) {
           super.setOutputFormat( format != null ? format : new OutputFormat( Method.XML, null, false ) );
       }
   
  @@ -208,7 +237,7 @@
   
       public void startElement( String namespaceURI, String localName,
                                 String rawName, Attributes attrs )
  -        throws SAXException
  +    throws SAXException
       {
           int          i;
           boolean      preserveSpace;
  @@ -218,136 +247,139 @@
           boolean      addNSAttr = false;
   
           try {
  -        if ( _printer == null )
  -            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
  +            if (_printer == null)
  +                throw new IllegalStateException( "SER002 No writer supplied for serializer" );
   
  -        state = getElementState();
  -        if ( isDocumentState() ) {
  -            // If this is the root element handle it differently.
  -            // If the first root element in the document, serialize
  -            // the document's DOCTYPE. Space preserving defaults
  -            // to that of the output format.
  -            if ( ! _started )
  +            state = getElementState();
  +            if (isDocumentState()) {
  +                // If this is the root element handle it differently.
  +                // If the first root element in the document, serialize
  +                // the document's DOCTYPE. Space preserving defaults
  +                // to that of the output format.
  +                if (! _started)
                       startDocument( ( localName == null || localName.length() == 0 ) ? rawName : localName );
  -        } else {
  -            // For any other element, if first in parent, then
  -            // close parent's opening tag and use the parnet's
  -            // space preserving.
  -            if ( state.empty )
  -                _printer.printText( '>' );
  -            // Must leave CData section first
  -            if ( state.inCData )
  -            {
  -                _printer.printText( "]]>" );
  -                state.inCData = false;
               }
  -            // Indent this element on a new line if the first
  -            // content of the parent element or immediately
  -            // following an element or a comment
  -            if ( _indenting && ! state.preserveSpace &&
  -                 ( state.empty || state.afterElement || state.afterComment) )
  -                _printer.breakLine();
  -        }
  -        preserveSpace = state.preserveSpace;
  +            else {
  +                // For any other element, if first in parent, then
  +                // close parent's opening tag and use the parnet's
  +                // space preserving.
  +                if (state.empty)
  +                    _printer.printText( '>' );
  +                // Must leave CData section first
  +                if (state.inCData) {
  +                    _printer.printText( "]]>" );
  +                    state.inCData = false;
  +                }
  +                // Indent this element on a new line if the first
  +                // content of the parent element or immediately
  +                // following an element or a comment
  +                if (_indenting && ! state.preserveSpace &&
  +                    ( state.empty || state.afterElement || state.afterComment))
  +                    _printer.breakLine();
  +            }
  +            preserveSpace = state.preserveSpace;
   
               //We remove the namespaces from the attributes list so that they will
               //be in _prefixes
               attrs = extractNamespaces(attrs);
   
  -        // Do not change the current element state yet.
  -        // This only happens in endElement().
  -            if ( rawName == null || rawName.length() == 0 ) {
  -                if ( localName == null )
  +            // Do not change the current element state yet.
  +            // This only happens in endElement().
  +            if (rawName == null || rawName.length() == 0) {
  +                if (localName == null)
                       throw new SAXException( "No rawName and localName is null" );
  -                if ( namespaceURI != null && ! namespaceURI.equals( "" ) ) {
  -                String prefix;
  -                prefix = getPrefix( namespaceURI );
  -                    if ( prefix != null && prefix.length() > 0 )
  -                    rawName = prefix + ":" + localName;
  +                if (namespaceURI != null && ! namespaceURI.equals( "" )) {
  +                    String prefix;
  +                    prefix = getPrefix( namespaceURI );
  +                    if (prefix != null && prefix.length() > 0)
  +                        rawName = prefix + ":" + localName;
                       else
                           rawName = localName;
  -                } else
  +                }
  +                else
                       rawName = localName;
  -            addNSAttr = true;
  -        }
  -
  -        _printer.printText( '<' );
  -        _printer.printText( rawName );
  -        _printer.indent();
  -
  -        // For each attribute print it's name and value as one part,
  -        // separated with a space so the element can be broken on
  -        // multiple lines.
  -        if ( attrs != null ) {
  -            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
  -                _printer.printSpace();
  +                addNSAttr = true;
  +            }
   
  -                name = attrs.getQName( i );
  -                    if ( name != null && name.length() == 0 ) {
  -                    String prefix;
  -                    String attrURI;
  +            _printer.printText( '<' );
  +            _printer.printText( rawName );
  +            _printer.indent();
  +
  +            // For each attribute print it's name and value as one part,
  +            // separated with a space so the element can be broken on
  +            // multiple lines.
  +            if (attrs != null) {
  +                for (i = 0 ; i < attrs.getLength() ; ++i) {
  +                    _printer.printSpace();
   
  -                    name = attrs.getLocalName( i );
  -                    attrURI = attrs.getURI( i );
  -                        if ( ( attrURI != null && attrURI.length() != 0 ) &&
  -                             ( namespaceURI == null || namespaceURI.length() == 0 ||
  -                                              ! attrURI.equals( namespaceURI ) ) ) {
  -                        prefix = getPrefix( attrURI );
  -                        if ( prefix != null && prefix.length() > 0 )
  -                            name = prefix + ":" + name;
  +                    name = attrs.getQName( i );
  +                    if (name != null && name.length() == 0) {
  +                        String prefix;
  +                        String attrURI;
  +
  +                        name = attrs.getLocalName( i );
  +                        attrURI = attrs.getURI( i );
  +                        if (( attrURI != null && attrURI.length() != 0 ) &&
  +                            ( namespaceURI == null || namespaceURI.length() == 0 ||
  +                              ! attrURI.equals( namespaceURI ) )) {
  +                            prefix = getPrefix( attrURI );
  +                            if (prefix != null && prefix.length() > 0)
  +                                name = prefix + ":" + name;
  +                        }
                       }
  -                }
  -
  -                value = attrs.getValue( i );
  -                if ( value == null )
  -                    value = "";
  -                _printer.printText( name );
  -                _printer.printText( "=\"" );
  -                printEscaped( value );
  -                _printer.printText( '"' );
  -
  -                // If the attribute xml:space exists, determine whether
  -                // to preserve spaces in this and child nodes based on
  -                // its value.
  -                if ( name.equals( "xml:space" ) ) {
  -                    if ( value.equals( "preserve" ) )
  -                        preserveSpace = true;
  -                    else
  -                        preserveSpace = _format.getPreserveSpace();
  -                }
  -            }
  -        }
   
  -            if ( _prefixes != null ) {
  -            Enumeration enum;
  -
  -            enum = _prefixes.keys();
  -            while ( enum.hasMoreElements() ) {
  -                _printer.printSpace();
  -                value = (String) enum.nextElement();
  -                name = (String) _prefixes.get( value );
  -                if ( name.length() == 0 ) {
  -                    _printer.printText( "xmlns=\"" );
  -                    printEscaped( value );
  -                    _printer.printText( '"' );
  -                } else {
  -                    _printer.printText( "xmlns:" );
  +                    value = attrs.getValue( i );
  +                    if (value == null)
  +                        value = "";
                       _printer.printText( name );
                       _printer.printText( "=\"" );
                       printEscaped( value );
                       _printer.printText( '"' );
  +
  +                    // If the attribute xml:space exists, determine whether
  +                    // to preserve spaces in this and child nodes based on
  +                    // its value.
  +                    if (name.equals( "xml:space" )) {
  +                        if (value.equals( "preserve" ))
  +                            preserveSpace = true;
  +                        else
  +                            preserveSpace = _format.getPreserveSpace();
  +                    }
  +                }
  +            }
  +
  +            if (_prefixes != null) {
  +                Enumeration enum;
  +
  +                enum = _prefixes.keys();
  +                while (enum.hasMoreElements()) {
  +                    _printer.printSpace();
  +                    value = (String) enum.nextElement();
  +                    name = (String) _prefixes.get( value );
  +                    if (name.length() == 0) {
  +                        _printer.printText( "xmlns=\"" );
  +                        printEscaped( value );
  +                        _printer.printText( '"' );
  +                    }
  +                    else {
  +                        _printer.printText( "xmlns:" );
  +                        _printer.printText( name );
  +                        _printer.printText( "=\"" );
  +                        printEscaped( value );
  +                        _printer.printText( '"' );
  +                    }
                   }
               }
  -        }
   
  -        // Now it's time to enter a new element state
  -        // with the tag name and space preserving.
  -        // We still do not change the curent element state.
  -        state = enterElementState( namespaceURI, localName, rawName, preserveSpace );
  +            // Now it's time to enter a new element state
  +            // with the tag name and space preserving.
  +            // We still do not change the curent element state.
  +            state = enterElementState( namespaceURI, localName, rawName, preserveSpace );
               name = ( localName == null || localName.length() == 0 ) ? rawName : namespaceURI + "^" + localName;
               state.doCData = _format.isCDataElement( name );
               state.unescaped = _format.isNonEscapingElement( name );
  -        } catch ( IOException except ) {
  +        }
  +        catch (IOException except) {
               throw new SAXException( except );
           }
       }
  @@ -355,37 +387,42 @@
   
       public void endElement( String namespaceURI, String localName,
                               String rawName )
  -        throws SAXException
  +    throws SAXException
       {
           try {
               endElementIO( namespaceURI, localName, rawName );
  -        } catch ( IOException except ) {
  +        }
  +        catch (IOException except) {
               throw new SAXException( except );
           }
       }
   
   
       public void endElementIO( String namespaceURI, String localName,
  -                            String rawName )
  -        throws IOException
  +                              String rawName )
  +    throws IOException
       {
           ElementState state;
  -
  +        fNamespaceSupport.popContext();
  +        if (DEBUG) {
  +            System.out.println("==>endElement: " +rawName);
  +        }
           // Works much like content() with additions for closing
           // an element. Note the different checks for the closed
           // element's state and the parent element's state.
           _printer.unindent();
           state = getElementState();
  -        if ( state.empty ) {
  +        if (state.empty) {
               _printer.printText( "/>" );
  -        } else {
  +        }
  +        else {
               // Must leave CData section first
  -            if ( state.inCData )
  +            if (state.inCData)
                   _printer.printText( "]]>" );
               // This element is not empty and that last content was
               // another element, so print a line break before that
               // last element and this element's closing tag.
  -            if ( _indenting && ! state.preserveSpace && (state.afterElement || state.afterComment) )
  +            if (_indenting && ! state.preserveSpace && (state.afterElement || state.afterComment))
                   _printer.breakLine();
               _printer.printText( "</" );
               _printer.printText( state.rawName );
  @@ -397,7 +434,7 @@
           state.afterElement = true;
           state.afterComment = false;
           state.empty = false;
  -        if ( isDocumentState() )
  +        if (isDocumentState())
               _printer.flush();
       }
   
  @@ -408,7 +445,7 @@
   
   
       public void startElement( String tagName, AttributeList attrs )
  -        throws SAXException
  +    throws SAXException
       {
           int          i;
           boolean      preserveSpace;
  @@ -417,86 +454,87 @@
           String       value;
   
           try {
  -        if ( _printer == null )
  -            throw new IllegalStateException( "SER002 No writer supplied for serializer" );
  +            if (_printer == null)
  +                throw new IllegalStateException( "SER002 No writer supplied for serializer" );
   
  -        state = getElementState();
  -        if ( isDocumentState() ) {
  -            // If this is the root element handle it differently.
  -            // If the first root element in the document, serialize
  -            // the document's DOCTYPE. Space preserving defaults
  -            // to that of the output format.
  -            if ( ! _started )
  -                startDocument( tagName );
  -        } else {
  -            // For any other element, if first in parent, then
  -            // close parent's opening tag and use the parnet's
  -            // space preserving.
  -            if ( state.empty )
  -                _printer.printText( '>' );
  -            // Must leave CData section first
  -            if ( state.inCData )
  -            {
  -                _printer.printText( "]]>" );
  -                state.inCData = false;
  +            state = getElementState();
  +            if (isDocumentState()) {
  +                // If this is the root element handle it differently.
  +                // If the first root element in the document, serialize
  +                // the document's DOCTYPE. Space preserving defaults
  +                // to that of the output format.
  +                if (! _started)
  +                    startDocument( tagName );
               }
  -            // Indent this element on a new line if the first
  -            // content of the parent element or immediately
  -            // following an element.
  -            if ( _indenting && ! state.preserveSpace &&
  -                 ( state.empty || state.afterElement || state.afterComment) )
  -                _printer.breakLine();
  -        }
  -        preserveSpace = state.preserveSpace;
  +            else {
  +                // For any other element, if first in parent, then
  +                // close parent's opening tag and use the parnet's
  +                // space preserving.
  +                if (state.empty)
  +                    _printer.printText( '>' );
  +                // Must leave CData section first
  +                if (state.inCData) {
  +                    _printer.printText( "]]>" );
  +                    state.inCData = false;
  +                }
  +                // Indent this element on a new line if the first
  +                // content of the parent element or immediately
  +                // following an element.
  +                if (_indenting && ! state.preserveSpace &&
  +                    ( state.empty || state.afterElement || state.afterComment))
  +                    _printer.breakLine();
  +            }
  +            preserveSpace = state.preserveSpace;
   
  -        // Do not change the current element state yet.
  -        // This only happens in endElement().
  +            // Do not change the current element state yet.
  +            // This only happens in endElement().
   
  -        _printer.printText( '<' );
  -        _printer.printText( tagName );
  -        _printer.indent();
  -
  -        // For each attribute print it's name and value as one part,
  -        // separated with a space so the element can be broken on
  -        // multiple lines.
  -        if ( attrs != null ) {
  -            for ( i = 0 ; i < attrs.getLength() ; ++i ) {
  -                _printer.printSpace();
  -                name = attrs.getName( i );
  -                value = attrs.getValue( i );
  -                if ( value != null ) {
  -                    _printer.printText( name );
  -                    _printer.printText( "=\"" );
  -                    printEscaped( value );
  -                    _printer.printText( '"' );
  -                }
  +            _printer.printText( '<' );
  +            _printer.printText( tagName );
  +            _printer.indent();
  +
  +            // For each attribute print it's name and value as one part,
  +            // separated with a space so the element can be broken on
  +            // multiple lines.
  +            if (attrs != null) {
  +                for (i = 0 ; i < attrs.getLength() ; ++i) {
  +                    _printer.printSpace();
  +                    name = attrs.getName( i );
  +                    value = attrs.getValue( i );
  +                    if (value != null) {
  +                        _printer.printText( name );
  +                        _printer.printText( "=\"" );
  +                        printEscaped( value );
  +                        _printer.printText( '"' );
  +                    }
   
  -                // If the attribute xml:space exists, determine whether
  -                // to preserve spaces in this and child nodes based on
  -                // its value.
  -                if ( name.equals( "xml:space" ) ) {
  -                    if ( value.equals( "preserve" ) )
  -                        preserveSpace = true;
  -                    else
  -                        preserveSpace = _format.getPreserveSpace();
  +                    // If the attribute xml:space exists, determine whether
  +                    // to preserve spaces in this and child nodes based on
  +                    // its value.
  +                    if (name.equals( "xml:space" )) {
  +                        if (value.equals( "preserve" ))
  +                            preserveSpace = true;
  +                        else
  +                            preserveSpace = _format.getPreserveSpace();
  +                    }
                   }
               }
  +            // Now it's time to enter a new element state
  +            // with the tag name and space preserving.
  +            // We still do not change the curent element state.
  +            state = enterElementState( null, null, tagName, preserveSpace );
  +            state.doCData = _format.isCDataElement( tagName );
  +            state.unescaped = _format.isNonEscapingElement( tagName );
           }
  -        // Now it's time to enter a new element state
  -        // with the tag name and space preserving.
  -        // We still do not change the curent element state.
  -        state = enterElementState( null, null, tagName, preserveSpace );
  -        state.doCData = _format.isCDataElement( tagName );
  -        state.unescaped = _format.isNonEscapingElement( tagName );
  -        } catch ( IOException except ) {
  +        catch (IOException except) {
               throw new SAXException( except );
  -    }
  +        }
   
       }
   
   
       public void endElement( String tagName )
  -        throws SAXException
  +    throws SAXException
       {
           endElement( null, null, tagName );
       }
  @@ -521,55 +559,56 @@
        * this is not the first root element of the document.
        */
       protected void startDocument( String rootTagName )
  -        throws IOException
  +    throws IOException
       {
           int    i;
           String dtd;
   
           dtd = _printer.leaveDTD();
  -        if ( ! _started ) {
  +        if (! _started) {
   
  -            if ( ! _format.getOmitXMLDeclaration() ) {
  +            if (! _format.getOmitXMLDeclaration()) {
                   StringBuffer    buffer;
   
                   // Serialize the document declaration appreaing at the head
                   // of very XML document (unless asked not to).
                   buffer = new StringBuffer( "<?xml version=\"" );
  -                if ( _format.getVersion() != null )
  +                if (_format.getVersion() != null)
                       buffer.append( _format.getVersion() );
                   else
                       buffer.append( "1.0" );
                   buffer.append( '"' );
  -                if ( _format.getEncoding() != null ) {
  +                if (_format.getEncoding() != null) {
                       buffer.append( " encoding=\"" );
                       buffer.append( _format.getEncoding() );
                       buffer.append( '"' );
                   }
  -                if ( _format.getStandalone() && _docTypeSystemId == null &&
  -                     _docTypePublicId == null )
  +                if (_format.getStandalone() && _docTypeSystemId == null &&
  +                    _docTypePublicId == null)
                       buffer.append( " standalone=\"yes\"" );
                   buffer.append( "?>" );
                   _printer.printText( buffer );
                   _printer.breakLine();
               }
   
  -            if ( ! _format.getOmitDocumentType() ) {
  -                if ( _docTypeSystemId != null ) {
  +            if (! _format.getOmitDocumentType()) {
  +                if (_docTypeSystemId != null) {
                       // System identifier must be specified to print DOCTYPE.
                       // If public identifier is specified print 'PUBLIC
                       // <public> <system>', if not, print 'SYSTEM <system>'.
                       _printer.printText( "<!DOCTYPE " );
                       _printer.printText( rootTagName );
  -                    if ( _docTypePublicId != null ) {
  +                    if (_docTypePublicId != null) {
                           _printer.printText( " PUBLIC " );
                           printDoctypeURL( _docTypePublicId );
  -                        if ( _indenting ) {
  +                        if (_indenting) {
                               _printer.breakLine();
  -                            for ( i = 0 ; i < 18 + rootTagName.length() ; ++i )
  +                            for (i = 0 ; i < 18 + rootTagName.length() ; ++i)
                                   _printer.printText( " " );
  -                        } else
  +                        }
  +                        else
                               _printer.printText( " " );
  -                    printDoctypeURL( _docTypeSystemId );
  +                        printDoctypeURL( _docTypeSystemId );
                       }
                       else {
                           _printer.printText( " SYSTEM " );
  @@ -578,7 +617,7 @@
   
                       // If we accumulated any DTD contents while printing.
                       // this would be the place to print it.
  -                    if ( dtd != null && dtd.length() > 0 ) {
  +                    if (dtd != null && dtd.length() > 0) {
                           _printer.printText( " [" );
                           printText( dtd, true, true );
                           _printer.printText( ']' );
  @@ -586,7 +625,8 @@
   
                       _printer.printText( ">" );
                       _printer.breakLine();
  -                } else if ( dtd != null && dtd.length() > 0 ) {
  +                }
  +                else if (dtd != null && dtd.length() > 0) {
                       _printer.printText( "<!DOCTYPE " );
                       _printer.printText( rootTagName );
                       _printer.printText( " [" );
  @@ -608,119 +648,442 @@
        * inbetween, but better optimized.
        */
       protected void serializeElement( Element elem )
  -        throws IOException
  +    throws IOException
       {
           Attr         attr;
           NamedNodeMap attrMap;
           int          i;
           Node         child;
           ElementState state;
  -        boolean      preserveSpace;
           String       name;
           String       value;
           String       tagName;
   
  +        String prefix;
  +        String uri;
  +
  +
  +        fLocalNSCount = 0;
  +        fSerializedCount = 0;
  +        // add new namespace context
  +        fNamespaceSupport.pushContext();
  +        if (DEBUG) {
  +            System.out.println("==>startElement: " +elem.getNodeName());
  +        }
           tagName = elem.getTagName();
           state = getElementState();
  -        if ( isDocumentState() ) {
  +        if (isDocumentState()) {
               // If this is the root element handle it differently.
               // If the first root element in the document, serialize
               // the document's DOCTYPE. Space preserving defaults
               // to that of the output format.
  -            if ( ! _started )
  +
  +            // check if document is DOM L1 document
  +            fDOML1 = (elem.getLocalName() == null)? true: false;
  +
  +            if (! _started)
                   startDocument( tagName );
  -        } else {
  +        }
  +        else {
               // For any other element, if first in parent, then
  -            // close parent's opening tag and use the parnet's
  +            // close parent's opening tag and use the parent's
               // space preserving.
  -            if ( state.empty )
  +            if (state.empty)
                   _printer.printText( '>' );
               // Must leave CData section first
  -            if ( state.inCData )
  -            {
  +            if (state.inCData) {
                   _printer.printText( "]]>" );
                   state.inCData = false;
               }
               // Indent this element on a new line if the first
               // content of the parent element or immediately
               // following an element.
  -            if ( _indenting && ! state.preserveSpace &&
  -                 ( state.empty || state.afterElement || state.afterComment) )
  +            if (_indenting && ! state.preserveSpace &&
  +                ( state.empty || state.afterElement || state.afterComment))
                   _printer.breakLine();
           }
  -        preserveSpace = state.preserveSpace;
   
           // Do not change the current element state yet.
           // This only happens in endElement().
  +        fPreserveSpace = state.preserveSpace;
   
  -        _printer.printText( '<' );
  -        _printer.printText( tagName );
  -        _printer.indent();
  -
  -        // Lookup the element's attribute, but only print specified
  -        // attributes. (Unspecified attributes are derived from the DTD.
  -        // For each attribute print it's name and value as one part,
  -        // separated with a space so the element can be broken on
  -        // multiple lines.
  +
  +        // -----------------------------------------
  +        // seach for new namespace binding attributes 
  +        // -----------------------------------------
  +        // 
           attrMap = elem.getAttributes();
  -        if ( attrMap != null ) {
  -            for ( i = 0 ; i < attrMap.getLength() ; ++i ) {
  +        int length = 0;
  +
  +        //-----------------------
  +        // get element uri/prefix
  +        //-----------------------
  +        uri = elem.getNamespaceURI();            
  +        prefix = elem.getPrefix();
  +
  +
  +        //----------------------
  +        // output element name
  +        //----------------------
  +        if ((uri !=null && prefix !=null ) && uri.length() == 0 && prefix.length()!=0) {
  +            // uri is an empty string and element has some prefix
  +            // the namespace alg later will fix up the namespace attributes
  +            // remove element prefix
  +            _printer.printText( '<' );
  +            _printer.printText( elem.getLocalName() );
  +            _printer.indent();
  +        }
  +        else {
  +            _printer.printText( '<' );
  +            _printer.printText( tagName );
  +            _printer.indent();
  +        }
  +
  +        // REVISIT: should we report error/warning if DOM 1 nodes mix with DOM 2 nodes?
  +
  +        // -----------------------------------------
  +        // Fix up namespaces for element: per DOM L3 
  +        // check if prefix/namespace is correct for current element
  +        // -----------------------------------------
  +        if (uri != null) {  // Element has a namespace
  +
  +            uri = fSymbolTable.addSymbol(uri);
  +            prefix = prefix == null ? fEmptySymbol :fSymbolTable.addSymbol(prefix);
  +            if (fNamespaceSupport.getURI(prefix) == uri) {
  +                // this namespace was declared at parent level
  +                // do nothing
  +
  +            }
  +            else {
  +                // the prefix is either undeclared 
  +                // or
  +                // conflict: the prefix is bound to another URI
  +
  +                // check if uri is an empty string && element has prefix
  +                if (uri == fEmptySymbol && prefix != fEmptySymbol) {
  +
  +                    // the element prefix is already removed above
  +                    prefix = fEmptySymbol;
  +                    if (fNamespaceSupport.getURI(prefix) !=null) {
  +                        // xmlns default namespace is bound to something
  +                        // undeclare it
  +
  +                        // print default namespace declaration
  +                        printNamespaceAttr(prefix, uri);
  +                        fNamespaceSupport.declarePrefix(prefix, uri);
  +                    }
  +                }
  +                else {
  +                    // add or modify local declaration
  +                    printNamespaceAttr(prefix, uri);
  +                    fNamespaceSupport.declarePrefix(prefix, uri);
  +                }
  +
  +            }
  +        }
  +        else { // Element has no namespace
  +
  +            int colon = tagName.indexOf(':');
  +            if (colon > -1) {
  +                //  DOM Level 1 node!
  +                int colon2 = tagName.lastIndexOf(':');
  +                if (colon != colon2) {
  +                    //not a QName: report an error
  +                    if (fDOMErrorHandler != null) {
  +                        modifyDOMError("Element's name is not a QName: "+tagName, DOMError.SEVERITY_ERROR);
  +                        boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
  +                        // REVISIT: should we terminate upon request?                        
  +                    }
  +                }
  +                else {
  +                    // if we got here no namespace processing was performed
  +                    // report warnings
  +                    if (fDOMErrorHandler != null) {
  +                        modifyDOMError("Element <"+tagName+"> does not belong to any namespace: prefix could be undeclared or bound to some namespace", DOMError.SEVERITY_WARNING);
  +                        boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
  +                    }
  +                }
  +            }
  +            else { // uri=null and no colon
  +
  +                if (fNamespaceSupport.getURI(fEmptySymbol) !=null) {
  +                    // there is a default namespace decl that is bound to something else
  +                    printNamespaceAttr(fEmptySymbol, fEmptySymbol);
  +                    fNamespaceSupport.declarePrefix(fEmptySymbol, uri);
  +
  +                }
  +            }
  +        }
  +
  +        // -----------------------------------------
  +        // Fix up namespaces for attributes: per DOM L3 
  +        // check if prefix/namespace is correct the attributes
  +        // -----------------------------------------
  +
  +        if (attrMap !=null) {
  +
  +            for (i = 0; i < attrMap.getLength(); i++) {
  +
                   attr = (Attr) attrMap.item( i );
  -                name = attr.getName();
                   value = attr.getValue();
  -                if ( value == null )
  -                    value = "";
  -                if ( attr.getSpecified() || !getFeature("discard-default-content") ) {
  -                    _printer.printSpace();
  -                    _printer.printText( name );
  -                    _printer.printText( "=\"" );
  -                    printEscaped( value );
  -                    _printer.printText( '"' );
  +                name = attr.getNodeName();
  +                if (DEBUG) {
  +                    System.out.println("==>process attribute: "+attr.getNodeName());
                   }
  -                // If the attribute xml:space exists, determine whether
  -                // to preserve spaces in this and child nodes based on
  -                // its value.
  -                if ( name.equals( "xml:space" ) ) {
  -                    if ( value.equals( "preserve" ) )
  -                        preserveSpace = true;
  -                    else
  -                        preserveSpace = _format.getPreserveSpace();
  +                uri = attr.getNamespaceURI();
  +
  +
  +
  +                if (uri != null) {  // attribute has namespace !=null
  +                    prefix = attr.getPrefix();
  +                    prefix = prefix == null ? fEmptySymbol :fSymbolTable.addSymbol(prefix);
  +                    String localpart = fSymbolTable.addSymbol( attr.getLocalName());
  +
  +                    uri = fSymbolTable.addSymbol(uri);
  +
  +                    // find if for this prefix a URI was already declared
  +                    String declaredURI =  fNamespaceSupport.getURI(prefix);
  +
  +                    // check if attribute is a namespace decl 
  +                    if (prefix == fXmlnsSymbol) { //xmlns:prefix
  +
  +                        // REVISIT: should we skip invalid xmlns declaration
  +                        //          xmlns:foo = "" ??
  +                        if (fNamespaceSupport.getURI(localpart) == null) {
  +                            // this declaration is not in the scope
  +                            printNamespaceAttr(localpart, value);
  +                            fNamespaceSupport.declarePrefix(localpart, value);
  +                        }
  +                        continue;
  +                    }
  +                    else if (localpart == fXmlnsSymbol && prefix == fEmptySymbol) { // xmlns
  +                        if (fNamespaceSupport.getURI(fEmptySymbol) == null) {
  +                            // this declaration is not in the scope
  +                            printNamespaceAttr(fEmptySymbol, value);
  +                            fNamespaceSupport.declarePrefix(fEmptySymbol, value);
  +                        }
  +                        continue;
  +
  +                    }
  +                    
  +                    if (prefix == fEmptySymbol || declaredURI != uri) {
  +                        // attribute has no prefix (default namespace decl does not apply to attributes) 
  +                        // OR
  +                        // attribute prefix is not declared
  +                        // OR
  +                        // conflict: attr URI does not match the prefix in scope
  +
  +                        name  = attr.getNodeName();
  +                        // Find if any prefix for attributes namespace URI is available
  +                        // in the scope
  +                        String declaredPrefix = fNamespaceSupport.getPrefix(uri);
  +                        if (declaredPrefix == null || declaredPrefix == fEmptySymbol) {
  +                            // could not find a prefix/prefix is empty string
  +                            if (DEBUG) {
  +                                System.out.println("==> cound not find prefix for the attribute: " +prefix);
  +                            }
  +                            if (prefix != fEmptySymbol) {
  +                                // no need to create a new prefix:
  +                                // use the one on the attribute
  +                            } else {                            
  +                                // create new prefix
  +                                prefix = "NS" +fNamespaceCounter++; 
  +                            }
  +                            // add declaration for the new prefix
  +                            printNamespaceAttr(prefix, uri);
  +                            fNamespaceSupport.declarePrefix(prefix, uri);
  +                        }  else {
  +                            // use the prefix that was found (declared previously for this URI
  +                            prefix = declaredPrefix;
  +                        }
  +                        name=prefix+":"+localpart;
  +                        // change prefix for this attribute
  +                    }
  +
  +                    printAttribute (name, (value==null)?fEmptySymbol:value, attr.getSpecified());
  +                }
  +                else { // attribute uri == null
  +
  +                    // data
  +                    name = attr.getNodeName();
  +                    int colon = name.indexOf(':');
  +                    int colon2 = name.lastIndexOf(':');
  +                    value = attr.getValue();
  +                    // check if attribute is a namespace decl 
  +                    if (name.startsWith(fXmlnsSymbol)) {
  +                        //
  +                        //  DOM Level 1 node!
  +                        // 
  +                        if (colon < 0) {  // xmlns decl
  +                            if (fNamespaceSupport.getURI(fEmptySymbol) == null) {
  +                                // this declaration is not in the scope
  +                                fNamespaceSupport.declarePrefix(fEmptySymbol, (value==null)?fEmptySymbol:value);
  +                            }
  +                            else {
  +                                // duplicate declaration
  +                                // skip
  +                                continue;
  +                            }
  +
  +                        }
  +                        else if (colon == colon2) { // xmlns:prefix decl
  +                            // get prefix
  +                            prefix = name.substring(6);
  +                            if (prefix.length() == 0) {
  +                                // report an error - invalid namespace declaration
  +                                if (fDOMErrorHandler != null) {
  +                                    modifyDOMError("Namespace declaration syntax is incorrect "+name, DOMError.SEVERITY_ERROR);
  +                                    boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
  +                                }
  +                                // REVISIT: skip invalid declaration?
  +                                // continue;
  +
  +                            }
  +                            else if (value != null && value.length() == 0) {
  +                                if (fDOMErrorHandler != null) {
  +                                    modifyDOMError("Namespace declaration syntax is incorrect "+name, DOMError.SEVERITY_ERROR);
  +                                    boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
  +                                }
  +                                // REVISIT: skip invalid declaration?
  +                                // continue;
  +                            }
  +                            else if (fNamespaceSupport.getURI(prefix) == null) {
  +                                // this declaration is not in the scope
  +                                fNamespaceSupport.declarePrefix(prefix, value);
  +
  +                            }
  +                        } else { // colon !=colon
  +                            // will report error for this case later in the code
  +                        }
  +
  +                    }
  +
  +                    if (colon > -1) {
  +                        //
  +                        //  DOM Level 1 node!
  +                        // 
  +                        if (colon != colon2) {
  +                            //not a QName: report an error
  +                            if (fDOMErrorHandler != null) {
  +                                modifyDOMError("Attribute's name is not a QName: "+name, DOMError.SEVERITY_ERROR);
  +                                boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);                                                        
  +                            }
  +
  +                        }
  +                        else {
  +                            // if we got here no namespace processing was performed
  +                            // report warnings
  +                            if (fDOMErrorHandler != null) {
  +                                modifyDOMError("Attribute '"+name+"' does not belong to any namespace: prefix could be undeclared or bound to some namespace", DOMError.SEVERITY_WARNING);
  +                                boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
  +                            }
  +                        }
  +
  +                        // REVISIT: should we skip invalid declarations?
  +                        printAttribute (name, (value==null)?fEmptySymbol:value, attr.getSpecified());
  +                    }
  +                    else { // uri=null and no colon
  +                        // no fix up is needed: default namespace decl does not 
  +                        // apply to attributes
  +
  +                        printAttribute (name, (value==null)?fEmptySymbol:value, attr.getSpecified());
  +                    }
  +
                   }
               }
           }
   
  +
  +
           // If element has children, then serialize them, otherwise
  -        // serialize en empty tag.
  -        if ( elem.hasChildNodes() ) {
  +        // serialize en empty tag.        
  +        if (elem.hasChildNodes()) {
               // Enter an element state, and serialize the children
               // one by one. Finally, end the element.
  -            state = enterElementState( null, null, tagName, preserveSpace );
  +            state = enterElementState( null, null, tagName, fPreserveSpace );
               state.doCData = _format.isCDataElement( tagName );
               state.unescaped = _format.isNonEscapingElement( tagName );
               child = elem.getFirstChild();
  -            while ( child != null ) {
  +            while (child != null) {
                   serializeNode( child );
                   child = child.getNextSibling();
               }
               endElementIO( null, null, tagName );
  -        } else {
  +        }
  +        else {
  +            if (DEBUG) {
  +                System.out.println("==>endElement: " +elem.getNodeName());
  +            }
  +            fNamespaceSupport.popContext();
               _printer.unindent();
               _printer.printText( "/>" );
               // After element but parent element is no longer empty.
               state.afterElement = true;
               state.afterComment = false;
               state.empty = false;
  -            if ( isDocumentState() )
  +            if (isDocumentState())
                   _printer.flush();
           }
       }
   
   
  -    protected String getEntityRef( int ch )
  -    {
  +
  +    /**
  +     * Serializes a namespace attribute with the given prefix and value for URI.
  +     * In case prefix is empty will serialize default namespace declaration.
  +     * 
  +     * @param prefix
  +     * @param uri
  +     * @exception IOException
  +     */
  +
  +    private void printNamespaceAttr(String prefix, String uri) throws IOException{
  +        _printer.printSpace();
  +        if (prefix == fEmptySymbol) {
  +            _printer.printText( fXmlnsSymbol );
  +        }
  +        else {
  +            _printer.printText( fXmlnsSymbol+ ":"+prefix );
  +        }
  +        _printer.printText( "=\"" );
  +        printEscaped( uri );
  +        _printer.printText( '"' );
  +    }
  +
  +    /**
  +     * Prints attribute. 
  +     * NOTE: xml:space attribute modifies output format
  +     * 
  +     * @param name
  +     * @param value
  +     * @param isSpecified
  +     * @exception IOException
  +     */
  +    private void printAttribute (String name, String value, boolean isSpecified) throws IOException{
  +
  +        if (isSpecified || !getFeature("discard-default-content")) {
  +            _printer.printSpace();
  +            _printer.printText( name );
  +            _printer.printText( "=\"" );
  +            printEscaped( value );
  +            _printer.printText( '"' );
  +        }
  +
  +        // If the attribute xml:space exists, determine whether
  +        // to preserve spaces in this and child nodes based on
  +        // its value.
  +        if (name.equals( "xml:space" )) {
  +            if (value.equals( "preserve" ))
  +                fPreserveSpace = true;
  +            else
  +                fPreserveSpace = _format.getPreserveSpace();
  +        }
  +    }
  +
  +    protected String getEntityRef( int ch ) {
           // Encode special XML characters into the equivalent character references.
           // These five are defined by default for all XML documents.
  -        switch ( ch ) {
  +        switch (ch) {
           case '<':
               return "lt";
           case '>':
  @@ -740,7 +1103,7 @@
        *
        */
       private Attributes extractNamespaces( Attributes attrs )
  -        throws SAXException
  +    throws SAXException
       {
           AttributesImpl attrsOnly;
           String         rawName;
  @@ -752,17 +1115,18 @@
           length = attrs.getLength();
           attrsOnly = new AttributesImpl( attrs );
   
  -        for ( i = length - 1 ; i >= 0 ; --i ) {
  +        for (i = length - 1 ; i >= 0 ; --i) {
               rawName = attrsOnly.getQName( i );
   
               //We have to exclude the namespaces declarations from the attributes
               //Append only when the feature http://xml.org/sax/features/namespace-prefixes"
               //is TRUE
  -            if ( rawName.startsWith( "xmlns" ) ) {
  +            if (rawName.startsWith( "xmlns" )) {
                   if (rawName.length() == 5) {
                       startPrefixMapping( "", attrs.getValue( i ) );
                       attrsOnly.removeAttribute( i );
  -                } else if (rawName.charAt(5) == ':') {
  +                }
  +                else if (rawName.charAt(5) == ':') {
                       startPrefixMapping(rawName.substring(6), attrs.getValue(i));
                       attrsOnly.removeAttribute( i );
                   }
  @@ -770,9 +1134,10 @@
           }
           return attrsOnly;
       }
  -    
  +
  +
       // *****************************
  -    
  +
       private void initFeatures() {
           fFeatures.put("normalize-characters",new Boolean(false));
           fFeatures.put("split-cdata-sections",new Boolean(true));
  @@ -783,7 +1148,7 @@
           fFeatures.put("format-canonical",new Boolean(false));
           fFeatures.put("format-pretty-print",new Boolean(false));
       }
  -    
  +
       private void checkAllFeatures() {
           if (getFeature("whitespace-in-element-content"))
               _format.setPreserveSpace(true);
  @@ -807,7 +1172,7 @@
        */
       public void setFeature(String name, 
                              boolean state)
  -                           throws DOMException {
  +    throws DOMException {
           if (name != null && fFeatures.containsKey(name))
               if (canSetFeature(name,state))
                   fFeatures.put(name,new Boolean(state));
  @@ -830,19 +1195,19 @@
        */
       public boolean canSetFeature(String name, boolean state) {
           if (name.equals("normalize-characters") && state)
  -                return false;
  +            return false;
           else if (name.equals("validation") && state)
  -                return false;
  +            return false;
           else if (name.equals("whitespace-in-element-content") && !state)
  -                return false;
  +            return false;
           else if (name.equals("format-canonical") && state)
  -                return false;
  +            return false;
           else if (name.equals("format-pretty-print") && state)
  -                return false;
  +            return false;
           else
  -                return true;
  +            return true;
       }   
  -    
  +
       /**
        * Look up the value of a feature.
        * <br>The feature name has the same form as a DOM hasFeature string
  @@ -855,7 +1220,7 @@
        *   recognize the feature name.
        */
       public boolean getFeature(String name)
  -                              throws DOMException {
  +    throws DOMException {
           Boolean state = (Boolean)fFeatures.get(name);
           if (state == null)
               throw new DOMException(DOMException.NOT_FOUND_ERR,"Feature "+name+" not found");
  @@ -875,7 +1240,7 @@
       public String getEncoding() {
           return fEncoding;
       }
  -    
  +
       /**
        *  The character encoding in which the output will be written. 
        * <br> The encoding to use when writing is determined as follows: If the 
  @@ -925,7 +1290,7 @@
       public String getNewLine() {
           return _format.getLineSeparator();
       }
  -    
  +
       /**
        *  The end-of-line sequence of characters to be used in the XML being 
        * written out. The only permitted values are these: 
  @@ -962,7 +1327,7 @@
       public DOMErrorHandler getErrorHandler() {
           return fDOMErrorHandler;
       }
  -    
  +
       /**
        *  The error handler that will receive error notifications during 
        * serialization. The node where the error occured is passed to this 
  @@ -995,7 +1360,7 @@
        */
       public boolean writeNode(java.io.OutputStream destination, 
                                Node wnode)
  -                             throws Exception {
  +    throws Exception {
           checkAllFeatures();
           try {
               setOutputByteStream(destination);
  @@ -1010,10 +1375,10 @@
               else
                   return false;
           }
  -        catch(NullPointerException npe) {
  +        catch (NullPointerException npe) {
               throw npe;
           }
  -        catch(IOException ioe) {
  +        catch (IOException ioe) {
               throw ioe;
           }
           fLastEncoding = getEncoding();
  @@ -1037,7 +1402,7 @@
        *   <code>DOMString</code>. 
        */
       public String writeToString(Node wnode)
  -                                throws DOMException {
  +    throws DOMException {
           checkAllFeatures();
           StringWriter destination = new StringWriter();
           try {
  @@ -1053,13 +1418,27 @@
               else
                   return null;
           }
  -        catch(IOException ioe) {
  +        catch (IOException ioe) {
               throw new DOMException(DOMException.DOMSTRING_SIZE_ERR,"The resulting string is too long to fit in a DOMString: "+ioe.getMessage());
           }
           fLastEncoding = getEncoding();
           return destination.toString();
       }
   
  +    public boolean reset() {
  +        super.reset();
  +        fNamespaceSupport.reset(fSymbolTable);
  +        fNamespaceCounter = 1;
  +        fLocalNSCount = 0;
  +        fSerializedCount = 0;
  +        fXmlSymbol = fSymbolTable.addSymbol("xml");
  +        fXmlnsSymbol = fSymbolTable.addSymbol("xmlns");
  +        fEmptySymbol=fSymbolTable.addSymbol("");
  +        return true;
  +
  +    }
  +
   }
  +
   
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org