@Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        Attributes2 atts2 = (Attributes2) atts;
        int idIndex = -1;
        int xmlIdIndex = -1;
        String xmlIdValue = null;
        boolean needsWrap = false;
        int len = atts2.getLength();
        for (int i = 0; i < len; i++) {
            String ns = atts2.getURI(i);
            String local = atts2.getLocalName(i);
            String type = atts2.getType(i);
            if ("id" == local && "" == ns && "http://www.xml-cml.org/schema" != uri) {
                idIndex = i;
                checkId("id", atts2.getValue(i));
                if ("ID" != type) {
                    needsWrap = true;
                }
            } else if ("id" == local && "http://www.w3.org/XML/1998/namespace" == ns) {
                xmlIdIndex = i;
                String value = atts2.getValue(i);
                String normalizedValue = avNormalize(value);
                if (value != normalizedValue) {
                    xmlIdValue = normalizedValue;
                    needsWrap = true;
                }
                Matcher m = NCNAME_PATTERN.matcher(normalizedValue);
                if (!m.matches()) {
                    super.error(new SAXParseException("\u201C" + normalizedValue + "\u201D is not a Namespaces in XML 1.0 NCName.", locator));                    
                }
                if ("ID" != type) {
                    needsWrap = true;
                    if (atts2.isDeclared(i)) {
                        super.error(new SAXParseException("The attribute \u201Cxml:id\u201D was declared to be of type " + type + "in the DTD although it is required to be declared to be of type ID.", locator));                                            
                    }
                }
                checkId("xml:id", normalizedValue);
            } else if ("ID" == type) {
                String qn = atts2.getQName(i);
                super.warning(new SAXParseException("Unusual attribute \u201C" + qn + "\u201D declared be of type ID. This may be a compatibility problem when the DTD is not processed.", locator));
                checkId(qn, atts2.getValue(i));
            }
        }
        if (needsWrap) {
            wrapper.setFields(atts, xmlIdIndex, idIndex, xmlIdValue);
            super.startElement(uri, localName, qName, wrapper);
        } else {
            super.startElement(uri, localName, qName, atts);
        }
    }
@see org.xml.sax.helpers.XMLFilterImpl#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
src/nu/validator/xml/IdFilter.java