private void parseElement ( boolean maybeGetSubset ) throws Exception { String gi ; char c ; int oldElementContent = currentElementContent ; String oldElement = currentElement ; ElementDecl element ; // This is the (global) counter for the // array of specified attributes. tagAttributePos = 0 ; // Read the element type name. gi = readNmtoken ( true ) ; // If we saw no DTD, and this is the document root element, // let the application modify the input stream by providing one. if ( maybeGetSubset ) { InputSource subset = handler . getExternalSubset ( gi , handler . getSystemId ( ) ) ; if ( subset != null ) { String publicId = subset . getPublicId ( ) ; String systemId = subset . getSystemId ( ) ; handler . warn ( "modifying document by adding DTD" ) ; handler . doctypeDecl ( gi , publicId , systemId ) ; pushString ( null , ">" ) ; // NOTE: [dtd] is so we say what SAX2 expects, // though it's misleading (subset, not entire dtd) pushURL ( true , "[dtd]" , new ExternalIdentifiers ( publicId , systemId , null ) , subset . getCharacterStream ( ) , subset . getByteStream ( ) , subset . getEncoding ( ) , false ) ; // Loop until we end up back at '>' while ( true ) { doReport = expandPE = true ; skipWhitespace ( ) ; doReport = expandPE = false ; if ( tryRead ( ' ' ) ) { break ; } else { expandPE = true ; parseMarkupdecl ( ) ; expandPE = false ; } } // the ">" string isn't popped yet if ( inputStack . size ( ) != 1 ) { fatal ( "external subset has unmatched '>'" ) ; } handler . endDoctype ( ) ; } } // Determine the current content type. currentElement = gi ; element = elementInfo . get ( gi ) ; currentElementContent = getContentType ( element , CONTENT_ANY ) ; // Read the attributes, if any. // After this loop, "c" is the closing delimiter. boolean white = tryWhitespace ( ) ; c = readCh ( ) ; while ( ( c != ' ' ) && ( c != ' ' ) ) { unread ( c ) ; if ( ! white ) { fatal ( "need whitespace between attributes" ) ; } parseAttribute ( gi ) ; white = tryWhitespace ( ) ; c = readCh ( ) ; } // Supply any defaulted attributes. Iterator < String > atts = declaredAttributes ( element ) ; if ( atts != null ) { String aname ; loop : while ( atts . hasNext ( ) ) { aname = atts . next ( ) ; // See if it was specified. for ( int i = 0 ; i < tagAttributePos ; i ++ ) { if ( tagAttributes [ i ] == aname ) { continue loop ; } } // ... or has a default String value = getAttributeDefaultValue ( gi , aname ) ; if ( value == null ) { continue ; } handler . attribute ( aname , value , false ) ; } } // Figure out if this is a start tag // or an empty element, and dispatch an // event accordingly. switch ( c ) { case ' ' : handler . startElement ( gi ) ; parseContent ( ) ; break ; case ' ' : require ( ' ' ) ; handler . startElement ( gi ) ; handler . endElement ( gi ) ; break ; } // Restore the previous state. currentElement = oldElement ; currentElementContent = oldElementContent ; }
Parse an element with its tags .