import org.xml.sax.*; 
import org.xml.sax.helpers.XMLReaderFactory; 

import java.io.FileInputStream; 
import java.io.IOException; 

public class SaxParserBug { 
  public static void main(String[] args) { 
    try { 
      new SaxParserBug().test(args.length > 0 ? args[0] : "Import.xml", false, false); 
      //larger file, where it occurs every ~5000 lines 
      //new SaxParserBug().test(args.length > 0 ? args[0] : "Orgeinheiten_Import.xml", false, false); 
    }catch(Exception e){ 
      e.printStackTrace(); 
    } 
  } 

  public void test(String filename, boolean readOnStartElement, boolean useApacheXerces) throws IOException, SAXException { 
    FileInputStream in = new FileInputStream(filename); 
    XMLReader parser; 
    if (useApacheXerces) { 
      //if using apache xerces parser, everything well. 
      parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); 
    }else { 
      //use jdk default, will fail, see below 
      parser = XMLReaderFactory.createXMLReader("com.sun.org.apache.xerces.internal.parsers.SAXParser"); 
    } 
    parser.setContentHandler(new TestContentHandler(readOnStartElement)); 
    parser.parse(new InputSource(in)); 
  } 

  public static class TestContentHandler implements ContentHandler { 
    private final boolean readOnStartElement; 
    private Attributes atts; 
    private int scount = 0; 
    private int ecount = 0; 

    public TestContentHandler(boolean readOnStartElement) { 
      this.readOnStartElement = readOnStartElement; 
    } 

    @Override 
    public void startElement(String s, String s1, String s2, Attributes attributes) throws SAXException { 
      atts = attributes; 

      if (readOnStartElement) { 
        //if reading attributes on start, everything well 
        String pattern = atts.getValue("pattern"); //$NON-NLS-1$ 
        if (pattern != null) { 
          if ("M/d/yyyy".equals(pattern)) { 
            //expected 
            scount++; 
          } else { 
            System.err.println("START wrong Pattern: " + pattern); 
          } 
        } 
      } 
    } 

    @Override 
    public void endElement(String s, String s1, String s2) throws SAXException { 
      //if reading attrs ONLY on end, fails sometimes 
      String pattern = atts.getValue("pattern"); //$NON-NLS-1$ 
      if (pattern != null) { 
        if ("M/d/yyyy".equals(pattern)) { 
          //expected 
          ecount++; 
        } else { 
          System.err.println("END Wrong Pattern: " + pattern); 
        } 
      } 
    } 

    @Override public void startDocument() throws SAXException { } 

    @Override 
    public void endDocument() throws SAXException { 
      if (scount>0) System.out.println("Got "+scount+" correct patterns on startElement"); 
      System.out.println("Got "+ecount+" correct patterns on endElement"); 
    } 

    @Override public void setDocumentLocator(Locator locator) { } 
    @Override public void startPrefixMapping(String s, String s1) throws SAXException { } 
    @Override public void endPrefixMapping(String s) throws SAXException { } 
    @Override public void characters(char[] chars, int i, int i1) throws SAXException { } 
    @Override public void ignorableWhitespace(char[] chars, int i, int i1) throws SAXException { } 
    @Override public void processingInstruction(String s, String s1) throws SAXException { } 
    @Override public void skippedEntity(String s) throws SAXException { } 
  } 
} 