title: SAXParseException: 'Attribute "" bound to namespace "null" was already specified for element "metric"'
body: <p>At work, we have just migrated an old web-app from struts 1.1 to 1.2.9 (hopefully first steps to moving to 1.3), but we are now having problems with the commons digester. Struts 1.2.9 uses commons-digester 1.6.</p>
  
  <p>When we try to parse one of our XML files we get the exception:</p>
  
  <pre><code>org.xml.sax.SAXParseException: Attribute "" bound to namespace "null" was already specified for element "metric".
      at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:232)
      at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:213)
      at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:385)
      at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:315)
      at org.apache.xerces.impl.dtd.XMLNSDTDValidator.startNamespaceScope(XMLNSDTDValidator.java:242)
      at org.apache.xerces.impl.dtd.XMLDTDValidator.handleStartElement(XMLDTDValidator.java:1980)
      at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(XMLDTDValidator.java:802)
      at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:313)
      at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(XMLNSDocumentScannerImpl.java:610)
      at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1608)
      at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:346)
      at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:529)
      at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:585)
      at org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:152)
      at org.apache.xerces.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1142)
      at org.apache.commons.digester.Digester.parse(Digester.java:1572)
      at com.foo.ctms.framework.metrics.parser.MetricsXMLParser$InternalDigester.parse(MetricsXMLParser.java:54)
      at com.foo.ctms.framework.metrics.parser.MetricsXMLParser.parse(MetricsXMLParser.java:40)
  </code></pre>
  
  <p>In investigating this issue I have tried to get a simplest possible case and this is what I currently have:</p>
  
  <pre><code>package com.foo.ctms.framework.metrics.parser;
  
  import org.apache.commons.digester.Digester;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  import java.io.IOException;
  import java.net.URL;
  
  /**
   * Class that provides methods for parsing metrics definitions defined via XML and populating an object graph of JavaBeans
   * representing the definition.
   * @version $Revision: 41470 $
   */
  public final class MetricsXMLParser {
    /**
     * The set of public identifiers, and corresponding resource names, for the versions of the configuration file DTD that we know
     * about.  The key is the name of the resource as in the XMl file, and the value is the location of the resource with respect to
     * the &lt;code&gt;ClassLoader&lt;/code&gt; that this code in running in.
     */
    private static final String registrations[] = {"-//Foo Inc.//DTD Portal Metrics 1.0//EN", "metrics.dtd"};
  
    private MetricsXMLParser() {
    }
  
    /**
     * Parses a metric definition specified as an &lt;code&gt;InputStream&lt;/code&gt;.
     * @param url The metrics definition to parse. Must not be &lt;code&gt;null&lt;/code&gt;.
     * @throws IOException  if an I/O error occured while attempting to parse
     * @throws SAXException if an XML parsing error occured
     */
    public static MetricDefinition parse(URL url)
            throws IOException, SAXException {
      InternalDigester digester = new InternalDigester();
      return digester.parse(url);
    }
  
    private static final class InternalDigester {
      private final Digester digester;
  
      /**
       * Parses a metric definition specified as an &lt;code&gt;InputStream&lt;/code&gt;.
       * @param input The metrics definition to parse. Must not be &lt;code&gt;null&lt;/code&gt;.
       * @throws IOException  if an I/O error occured while attempting to parse
       * @throws SAXException if an XML parsing error occured
       */
      public MetricDefinition parse(URL input)
              throws IOException, SAXException {
        return (MetricDefinition)digester.parse(new InputSource(input.toString()));
      }
  
      private InternalDigester() {
        digester = new Digester();
        digester.setValidating(true);
        for (int i = 0; i &lt; MetricsXMLParser.registrations.length; i += 2) {
          URL url = getClass().getResource(MetricsXMLParser.registrations[i + 1]);
          if (url != null) {
            digester.register(MetricsXMLParser.registrations[i], url.toString());
          }
        }
  
        digester.addObjectCreate("metric", MetricDefinition.class);
        digester.addSetProperties("metric");
      }
    }
  }
  </code></pre>
  
  <p>which is given the XML:</p>
  
  <pre><code>&lt;?xml version='1.0' encoding='windows-1252'?&gt;
  &lt;!DOCTYPE metric PUBLIC "-//Foo Inc.//DTD Portal Metrics 1.0//EN" "metrics.dtd"&gt;
  
  &lt;metric name="metricsConfig" defaultView="trials"&gt;
  
  &lt;/metric&gt;
  </code></pre>
  
  <p>The DTD is currently down to:
      </p>
  
  <pre><code>&lt;!-- A metric element is the document root --&gt;
  &lt;!ELEMENT metric ANY&gt;
  
  &lt;!-- A metric has a name and a default view.  The default view must
       exactly match the name of one of the nested views --&gt;
  &lt;!ATTLIST metric
      name CDATA #REQUIRED
      defaultView CDATA #IMPLIED
  &gt;
  </code></pre>
  
  <p>Does anyone know what I am doing wrong? </p>
  
  <p>If I remove the defaultView attribute I do not get the error. </p>
  
  <hr>
  
  <p>As per sfussenegger's suggestion I've now tried the following (non-digester) code:</p>
  
  <pre><code>try {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setNamespaceAware(false);
    factory.setValidating(true);
    SAXParser parser = factory.newSAXParser();
    XMLReader reader = parser.getXMLReader();
    reader.parse(new InputSource(url.toString()));
  } catch (Exception e) {
    e.printStackTrace();
  }
  </code></pre>
  
  <p>and couldn't reproduce the problem, but adding the following (which commons-digester also does in XercesParser) prior to using my factory gives the same exception:</p>
  
  <pre><code>factory.setFeature("http://apache.org/xml/features/validation/dynamic", true);
  factory.setFeature("http://apache.org/xml/features/validation/schema", true);
  </code></pre>
  
  <p>In the end we have decided to try out a more modern version of xerces (2.7.1) and that seems to work.</p>