Class XHTMLBalancingHandler
- All Implemented Interfaces:
ContentHandler, DTDHandler, EntityResolver, ErrorHandler
The decorator is a thin passthrough on the happy path: it pushes and pops an
internal stack on startElement/endElement and otherwise forwards
every event to the wrapped handler unchanged. It deliberately does NOT mask
bad event sequences (mismatched or excess endElement, duplicate attributes,
etc.) -- those remain visible to StrictXHTMLValidator so parser bugs
still surface as test failures.
The unhappy path -- a per-part SAX parser throwing mid-element after emitting
one or more start tags -- is handled via drainOpenElements(), which
emits a matching endElement (with the original uri/localName/qName)
for every element still on the stack, in reverse open order. The wrapped
handler is left in a well-formed state with no dangling elements from the
failed sub-parse.
Typical use wraps the handler that receives events from an inner SAX parser, inside the catch arm that swallows the inner parser's exception:
XHTMLBalancingHandler balancer = new XHTMLBalancingHandler(contentHandler);
try {
XMLReaderUtils.parseSAX(stream, new EmbeddedContentHandler(balancer), context);
} catch (SAXException e) {
balancer.drainOpenElements();
// ... log and continue ...
}
This handler does not touch startDocument/endDocument; the
caller still owns the document lifecycle.-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidEmits a matchingendElementfor every element still on the open stack, in reverse open order.voidendElement(String uri, String localName, String qName) intNumber of elements currently open through this handler.voidstartElement(String uri, String localName, String qName, Attributes attrs) Methods inherited from class ContentHandlerDecorator
characters, endDocument, endPrefixMapping, error, fatalError, handleException, ignorableWhitespace, processingInstruction, setContentHandler, setDocumentLocator, skippedEntity, startDocument, startPrefixMapping, toString, warningMethods inherited from class DefaultHandler
notationDecl, resolveEntity, unparsedEntityDeclMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface ContentHandler
declaration
-
Constructor Details
-
XHTMLBalancingHandler
-
-
Method Details
-
startElement
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException - Specified by:
startElementin interfaceContentHandler- Overrides:
startElementin classContentHandlerDecorator- Throws:
SAXException
-
endElement
- Specified by:
endElementin interfaceContentHandler- Overrides:
endElementin classContentHandlerDecorator- Throws:
SAXException
-
drainOpenElements
Emits a matchingendElementfor every element still on the open stack, in reverse open order. After this call the stack is empty.Intended for the catch arm of a caller that swallowed a
SAXExceptionfrom an inner SAX parser: the inner parser may have left one or more elements open mid-stream, and downstream serialization needs matching closers before any further events.Does NOT emit
endDocument-- document lifecycle stays with the caller.- Throws:
SAXException
-
openElementCount
public int openElementCount()Number of elements currently open through this handler. Exposed for tests and for callers that want to know whetherdrainOpenElements()would emit anything.
-