2013-12-09 11 views
6

Provo ad analizzare due documenti XML: <root/> e <root xmlns="hallo"/>. Il primo caso funziona bene, ma il caso successivo genera un'eccezione (xalan/xerces utilizzato è quello fornito con OpenJDK 1.6/1.7). Alcuni googling suggeriscono che ciò avvenga a causa dell'uso di uno spazio dei nomi XML senza prefisso. Analizzare un documento del genere sembra piuttosto normale che esotico per me, quindi mi chiedo come risolvere il problema.Analizza XML con spazio dei nomi senza prefisso: NAMESPACE_ERR

Tutte le altre persone che ho trovato che segnalano il problema hanno avuto il problema nel contesto di un'applicazione SOAP e hanno provato a fare alcune cose sofisticate, ma non sono riuscito a trovare nessuno con una configurazione semplice come la mia.

Alcune persone hanno suggerito che l'aggiornamento di xalan alla v2.7 risolva il problema. Non so quale versione sia stata distribuita con OpenJDK, ma ho provato a inserire esplicitamente la v2.7.1 sul classpath e nulla è cambiato. (Come posso verificare che questa sia la versione effettivamente utilizzata?).

Eventuali soluzioni alternative?

Ecco un test con il mio problema:

public class DemoTest { 

    @Test(dataProvider = "provide_xml") 
    public void transform_doesNotThrowException(final String xml) throws Exception { 
    final SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); 
    final SAXSource saxSource = new SAXSource(saxParser.getXMLReader(), new InputSource(new StringReader(xml))); 

    final Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
    final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 
    final DOMResult result = new DOMResult(document); 
    transformer.transform(saxSource, result); 
    } 

    @DataProvider 
    public Object[][] provide_xml() { 
    return new Object[][]{ 
     {"<root/>"}, // works 
     {"<root xmlns=\"hello\"/>"} // broken 
    }; 
    } 
} 

Ecco l'eccezione generata:

ERROR: 'NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.' 
javax.xml.transform.TransformerException: org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:720) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:317) 
    at de.smotive.server.resource.ResourceManagerTest.testName(ResourceManagerTest.java:36) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:641) 
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:677) 
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:850) 
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1154) 
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:137) 
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:121) 
    at org.testng.TestRunner.runWorkers(TestRunner.java:1108) 
    at org.testng.TestRunner.privateRun(TestRunner.java:737) 
    at org.testng.TestRunner.run(TestRunner.java:596) 
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:315) 
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:310) 
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:272) 
    at org.testng.SuiteRunner.run(SuiteRunner.java:221) 
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1027) 
    at org.testng.TestNG.runSuitesLocally(TestNG.java:964) 
    at org.testng.TestNG.run(TestNG.java:896) 
    at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:89) 
    at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:144) 
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:111) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:616) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. 
    at com.sun.org.apache.xerces.internal.dom.AttrNSImpl.setName(AttrNSImpl.java:108) 
    at com.sun.org.apache.xerces.internal.dom.AttrNSImpl.<init>(AttrNSImpl.java:77) 
    at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createAttributeNS(CoreDocumentImpl.java:2142) 
    at com.sun.org.apache.xerces.internal.dom.ElementImpl.setAttributeNS(ElementImpl.java:659) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:213) 
    at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:208) 
    at com.sun.org.apache.xml.internal.serializer.ToSAXHandler.flushPending(ToSAXHandler.java:281) 
    at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:247) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:604) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183) 
    at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(XMLDTDValidator.java:814) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1320) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1293) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3080) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:899) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:625) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:819) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:748) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1208) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:525) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:640) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:711) 
    ... 32 more 
--------- 
org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. 
    at com.sun.org.apache.xerces.internal.dom.AttrNSImpl.setName(AttrNSImpl.java:108) 
    at com.sun.org.apache.xerces.internal.dom.AttrNSImpl.<init>(AttrNSImpl.java:77) 
    at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createAttributeNS(CoreDocumentImpl.java:2142) 
    at com.sun.org.apache.xerces.internal.dom.ElementImpl.setAttributeNS(ElementImpl.java:659) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.SAX2DOM.startElement(SAX2DOM.java:213) 
    at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.closeStartTag(ToXMLSAXHandler.java:208) 
    at com.sun.org.apache.xml.internal.serializer.ToSAXHandler.flushPending(ToSAXHandler.java:281) 
    at com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler.endElement(ToXMLSAXHandler.java:247) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:604) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183) 
    at com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.emptyElement(XMLDTDValidator.java:814) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1320) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$ContentDriver.scanRootElementHook(XMLDocumentScannerImpl.java:1293) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3080) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:899) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:625) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:488) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:819) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:748) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1208) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:525) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:640) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:711) 
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:317) 
    at de.smotive.server.resource.ResourceManagerTest.testName(ResourceManagerTest.java:36) 

risposta

5

Si sta tentando di analizzare un documento namespace con un parser non-namespace-aware.

Per impostazione predefinita, i parser SAX e DOM non sono compatibili con lo spazio dei nomi, è necessario chiamare esplicitamente lo setNamespace() in fabbrica. Cambia il tuo codice per assomigliare al seguente e dovresti andare:

SAXParserFactory spf = SAXParserFactory.newInstance(); 
spf.setNamespaceAware(true); 
final SAXParser saxParser = spf.newSAXParser(); 
+0

wow, era così. Il messaggio di errore ha sicuramente margini di miglioramento. A volte può essere così facile. – yankee

Problemi correlati