2009-10-23 178 views
0

在工作中,我們剛剛將舊的web應用程序從struts 1.1遷移到1.2.9(希望首先轉移到1.3),但我們現在在普通消化器方面有問題。 Struts 1.2.9使用commons-digester 1.6。SAXParseException:'屬性'「綁定到名稱空間」null「已經爲元素」metric「指定'

當我們試圖分析我們的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 
> 

有沒有人知道我在做什麼錯?

如果我刪除defaultView屬性,我不會收到錯誤。


按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

難道你不能刪除公共沼氣池重現問題?看起來異常是完全解析相關的。因此,對於普通的SAX解析應該是一樣的。 – sfussenegger 2009-10-23 10:11:34

回答

1

問題似乎是由於commons-digester 1.6和xerces(XercesParser中的調用2.2)之間的不兼容性導致的,因此轉向更新版本的xerces(2.7.1)已經解決了這個問題。

我們選擇了這個版本的庫,因爲我們擁有的其他Web應用程序已經在使用它。

+0

這對我有效。你救了我!! – jacosta 2012-10-08 18:10:23

相關問題