Simultaneously with parsing, SAX can perform document validation. I.e. if the document has a DOCTYPE associated and SAX was said to validate the document, parser will notify the handler about all data-errors occurred.

The handler has to override error-related methods in order to listen validation events. There are three error-levels: warning, error and fatal error. If error occurred is fatal, by default SAX-parser aborts reading the file.

<!-- file: sample.xml -->
<?xml version="1.0"?>

<!DOCTYPE purchase-order [
	<!-- declaration of the root element and its attributes -->
	<!ELEMENT purchase-order (purchased-by, order-items)>
	<!ATTLIST purchase-order
		date   CDATA #REQUIRED
		number CDATA #REQUIRED
	>

   <!ELEMENT purchased-by (address)>
	<!ATTLIST purchased-by
	   name CDATA #REQUIRED
	>
	<!ELEMENT address (#PCDATA)>

	<!-- order-items can contains at least on item -->
   <!ELEMENT order-items (item+)>
	<!ELEMENT item EMPTY>
	<!ATTLIST item
		code  CDATA #REQUIRED
		type  CDATA #REQUIRED
		label CDATA #REQUIRED
	>
]>

<!--
   In order to constrain the contents of XML-document
	a DTD-definition may be used.
	The DTD-definition can be inserted immediately into
	the caption of target XML-file.
-->

<purchase-order date="2005-10-31" number="12345">

	<purchased-by name="My name">
<!--
		we comment it to lead an error:
		<address>My address</address>
	-->
	</purchased-by>

	<order-items>
		<!--
			here is an example of empty element
			i.e. containing no nested elements
		-->
		<item code="687" type="CD" label="Some music" />
		<item code="129851" type="DVD" label="Some video"/>
	</order-items>

</purchase-order>

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class SampleOfHandlingErrors {
    /**
     * Application entry point
     * @param args command-line arguments
     */
    public static void main(String[] args) {
        try {
            // creates and returns new instance of SAX-implementation:
            SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(true);
            
            // create SAX-parser...
            SAXParser parser = factory.newSAXParser();
            
            // .. define our handler:
            SaxHandler handler = new SaxHandler();
            
            // and parse:
            parser.parse("sample.xml", handler);
            
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }
    
    /**
     * Our own implementation of SAX handler reading
     * a purchase-order data.
     */
    private static final class SaxHandler extends DefaultHandler {
        
        // we enter to element 'qName':
        public void startElement(String uri, String localName, 
                    String qName, Attributes attrs) throws SAXException {
            
            if (qName.equals("purchase-order")) {
                // ... here process element start:
            }
        }
        
        // this is called when document is not valid:
        public void error(SAXParseException ex) throws SAXException {
            System.out.println("ERROR: [at " + ex.getLineNumber() +
                    "] " + ex);
        }
        
        // this is called when document is not well-formed:
        public void fatalError(SAXParseException ex) throws SAXException {
            System.out.println("FATAL_ERROR: [at " + 
                    ex.getLineNumber() + "] " + ex);
        }
        
        public void warning(SAXParseException ex) throws SAXException {
            System.out.println("WARNING: [at " + 
                    ex.getLineNumber() + "] " + ex);
        }
    }
}