public void startElement()

in src/org/apache/xml/serialize/HTMLSerializer.java [193:371]


    public void startElement( String namespaceURI, String localName,
                              String rawName, Attributes attrs )
        throws SAXException
    {
        int          i;
        boolean      preserveSpace;
        ElementState state;
        String       name;
        String       value;
        String       htmlName;
        boolean      addNSAttr = false;

        try {
            if ( _printer == null )
            	throw new IllegalStateException( 
				    DOMMessageFormatter.formatMessage(
				    DOMMessageFormatter.SERIALIZER_DOMAIN,
                    "NoWriterSupplied", null));

            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( '>' );
                // 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 ) )
                    _printer.breakLine();
            }
            preserveSpace = state.preserveSpace;

            // Do not change the current element state yet.
            // This only happens in endElement().
            
            // As per SAX2, the namespace URI is an empty string if the element has no
            // namespace URI, or namespaces is turned off. The check against null protects
            // against broken SAX implementations, so I've left it there. - mrglavas
            boolean hasNamespaceURI = (namespaceURI != null && namespaceURI.length() != 0);

            // SAX2: rawName (QName) could be empty string if 
            // namespace-prefixes property is false.
            if ( rawName == null || rawName.length() == 0) {
                rawName = localName;
                if ( hasNamespaceURI ) {
                    String prefix;
                    prefix = getPrefix( namespaceURI );
                    if ( prefix != null && prefix.length() != 0 )
                        rawName = prefix + ":" + localName;
                }
                addNSAttr = true;
            }
            if ( !hasNamespaceURI )
                htmlName = rawName;
            else {
                if ( namespaceURI.equals( XHTMLNamespace ) ||
                        (fUserXHTMLNamespace != null && fUserXHTMLNamespace.equals(namespaceURI)) )
                    htmlName = localName;
                else
                    htmlName = null;
            }

            // XHTML: element names are lower case, DOM will be different
            _printer.printText( '<' );
            if ( _xhtml )
                _printer.printText( rawName.toLowerCase(Locale.ENGLISH) );
            else
                _printer.printText( rawName );
            _printer.indent();

            // For each attribute serialize 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.getQName( i ).toLowerCase(Locale.ENGLISH);
                    value = attrs.getValue( i );
                    if ( _xhtml || hasNamespaceURI ) {
                        // XHTML: print empty string for null values.
                        if ( value == null ) {
                            _printer.printText( name );
                            _printer.printText( "=\"\"" );
                        } else {
                            _printer.printText( name );
                            _printer.printText( "=\"" );
                            printEscaped( value );
                            _printer.printText( '"' );
                        }
                    } else {
                        // HTML: Empty values print as attribute name, no value.
                        // HTML: URI attributes will print unescaped
                        if ( value == null ) {
                            value = "";
                        }
                        if ( !_format.getPreserveEmptyAttributes() && value.length() == 0 )
                            _printer.printText( name );
                        else if ( HTMLdtd.isURI( rawName, name ) ) {
                            _printer.printText( name );
                            _printer.printText( "=\"" );
                            _printer.printText( escapeURI( value ) );
                            _printer.printText( '"' );
                        } else if ( HTMLdtd.isBoolean( rawName, name ) )
                            _printer.printText( name );
                        else {
                            _printer.printText( name );
                            _printer.printText( "=\"" );
                            printEscaped( value );
                            _printer.printText( '"' );
                        }
                    }
                }
            }
            if ( htmlName != null && HTMLdtd.isPreserveSpace( htmlName ) )
                preserveSpace = true;

            if ( addNSAttr ) {
                Iterator entries = _prefixes.entrySet().iterator();
                while (entries.hasNext()) {
                    _printer.printSpace();
                    Map.Entry entry = (Map.Entry) entries.next();
                    value = (String) entry.getKey();
                    name = (String) entry.getValue();
                    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 );

            // Prevents line breaks inside A/TD

            if ( htmlName != null && ( htmlName.equalsIgnoreCase( "A" ) ||
                                       htmlName.equalsIgnoreCase( "TD" ) ) ) {
                state.empty = false;
                _printer.printText( '>' );
            }

            // Handle SCRIPT and STYLE specifically by changing the
            // state of the current element to CDATA (XHTML) or
            // unescaped (HTML).
            if ( htmlName != null && ( rawName.equalsIgnoreCase( "SCRIPT" ) ||
                                       rawName.equalsIgnoreCase( "STYLE" ) ) ) {
                if ( _xhtml ) {
                    // XHTML: Print contents as CDATA section
                    state.doCData = true;
                } else {
                    // HTML: Print contents unescaped
                    state.unescaped = true;
                }
            }
        } catch ( IOException except ) {
            throw new SAXException( except );
        }
    }