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 );
}
}