if (validating && doctype != null) {  AttributeDecl decl = doctype.getAttributeDecl(elementName, attributeName); if (decl == null) error("attribute must be declared", attributeName); if ("ENUMERATION".equals(decl.type)) {  if (!decl.values.contains(value)) error("value does not match enumeration " + decl.enumeration, value); } else if ("ID".equals(decl.type)) {  if (!isNmtoken(value, true)) error("ID values must match the Name production"); if (ids.contains(value)) error("Duplicate ID", value); ids.add(value); } else if ("IDREF".equals(decl.type) || "IDREFS".equals(decl.type)) { StringTokenizer st = new StringTokenizer(value); while (st.hasMoreTokens()) { String token = st.nextToken();  if (!isNmtoken(token, true)) error("IDREF values must match the Name production"); idrefs.add(token); } } else if ("NMTOKEN".equals(decl.type) || "NMTOKENS".equals(decl.type)) { StringTokenizer st = new StringTokenizer(value); while (st.hasMoreTokens()) { String token = st.nextToken();  if (!isNmtoken(token, false)) error("NMTOKEN values must match the Nmtoken production"); } } else if ("ENTITY".equals(decl.type)) {  if (!isNmtoken(value, true)) error("ENTITY values must match the Name production"); Object entity = doctype.getEntity(value); if (entity == null || !(entity instanceof ExternalIds) || ((ExternalIds) entity).notationName == null) error("ENTITY values must match the name of an unparsed " + "entity declared in the DTD"); } else if ("NOTATION".equals(decl.type)) { if (!decl.values.contains(value)) error("NOTATION values must match a declared notation name", value);  ExternalIds notation = doctype.getNotation(value); if (notation == null) error("NOTATION values must match the name of a notation " + "declared in the DTD", value); } }
  private void readAttribute(String elementName)    throws IOException, XMLStreamException  {    //System.err.println("readAttribute");    // Read attribute name    String attributeName = readNmtoken(true);    String type = getAttributeType(elementName, attributeName);    readEq();    // Read literal    final int flags = LIT_ATTRIBUTE |  LIT_ENTITY_REF;    String value = (type == null || "CDATA".equals(type)) ?      readLiteral(flags) : readLiteral(flags | LIT_NORMALIZE);    // add attribute event    Attribute attr = this.new Attribute(attributeName, type, true, value);    if (namespaceAware)      {        if (attributeName.equals(":"))          error("XML Namespaces forbids names consisting of a single colon");        else if (attributeName.equals("xmlns"))      {        LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();        if (ctx.containsKey(XMLConstants.DEFAULT_NS_PREFIX))          error("duplicate default namespace");      }        else if (attributeName.startsWith("xmlns:"))      {        LinkedHashMap ctx = (LinkedHashMap) namespaces.getFirst();        if (ctx.containsKey(attributeName.substring(6)))          error("duplicate namespace", attributeName.substring(6));      }        else if (attrs.contains(attr))          error("duplicate attribute", attributeName);      }    else if (attrs.contains(attr))      error("duplicate attribute", attributeName);    if (namespaceAware)      {        if (!addNamespace(attr))          attrs.add(attr);      }    else      attrs.add(attr);  }