SAXParseException: "سمة" "متجهة إلى مساحة الاسم" لاغية "تم تحديد بالفعل لعنصر" متري ""

StackOverflow https://stackoverflow.com/questions/1612411

سؤال

وفي العمل، ونحن هاجروا مجرد القديم التطبيق على شبكة الإنترنت من الدعامات 1.1 إلى 1.2.9 (الخطوات الأولى لنأمل أن ينتقل إلى 1.3)، ولكننا نواجه الآن مشاكل مع هاضم المشتركة. الدعامات 1.2.9 يستخدم المشاع-هاضم 1.6.

وعندما نحاول تحليل واحد من ملفات XML لدينا نحصل على استثناء:

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)

ولقد حاولت في التحقيق في هذه القضية للحصول على أبسط الحالات الممكنة وهذا ما لدي حاليا:

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 <code>ClassLoader</code> 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 <code>InputStream</code>.
   * @param url The metrics definition to parse. Must not be <code>null</code>.
   * @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 <code>InputStream</code>.
     * @param input The metrics definition to parse. Must not be <code>null</code>.
     * @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 < 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");
    }
  }
}

والذي يتم إعطاء XML:

<?xml version='1.0' encoding='windows-1252'?>
<!DOCTYPE metric PUBLIC "-//Foo Inc.//DTD Portal Metrics 1.0//EN" "metrics.dtd">

<metric name="metricsConfig" defaultView="trials">

</metric>

ووDTD حاليا وصولا الى:     

<!-- A metric element is the document root -->
<!ELEMENT metric ANY>

<!-- A metric has a name and a default view.  The default view must
     exactly match the name of one of the nested views -->
<!ATTLIST metric
    name CDATA #REQUIRED
    defaultView CDATA #IMPLIED
>

لا أحد يعرف ما أقوم به خطأ؟

إذا كنت إزالة طريقة_العرض_الافتراضية السمة أنا لا أحصل على الخطأ.


وحسب اقتراح sfussenegger ولقد حاولت الآن التعليمة البرمجية التالية (غير هاضم):

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();
}

و لا يمكن إعادة إنشاء المشكلة، لكنه اضاف ان التالية (التي لا المشاعات-هاضم أيضا في XercesParser) قبل استخدام بلدي مصنع يعطي نفس استثناء:

factory.setFeature("http://apache.org/xml/features/validation/dynamic", true);
factory.setFeature("http://apache.org/xml/features/validation/schema", true);

في نهاية قررنا أن يجرب نسخة أكثر حداثة من xerces (2.7.1) والذي يبدو للعمل.

هل كانت مفيدة؟

المحلول

ويبدو أن المشكلة ليكون ناجما عن عدم توافق بين المشاعات-هاضم 1.6 و xerces (دعوة في XercesParser يقول 2.2)، والانتقال إلى إصدار أحدث من xerces (2.7.1) وحددت المشكلة.

ولقد اخترنا هذا الإصدار من مكتبة لتطبيقات الويب الأخرى التي قد تستخدم بالفعل ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top