2013-12-09 10 views
6

Próbuję przeanalizować dwa dokumenty XML: <root/> i <root xmlns="hallo"/>. Pierwszy przypadek działa dobrze, ale późniejszy przypadek rzuca wyjątek (xalan/xerces używany jest z OpenJDK 1.6/1.7). Niektóre metody googlowania sugerują, że dzieje się tak z powodu użycia przestrzeni nazw XML bez prefiksu. Parsowanie takiego dokumentu wydaje mi się raczej normalne niż egzotyczne, więc zastanawiam się, jak obejść ten problem.Parsowanie XML z przestrzenią nazw bez prefiksu: NAMESPACE_ERR

Wszystkie inne osoby, z którymi zgłosiłem problem, miały problem w kontekście aplikacji SOAP i próbowały wykonać pewne skomplikowane czynności, ale nie mogłem znaleźć nikogo z prostą konfiguracją, taką jak moja.

Niektórzy sugerowali, że aktualizacja xalana do wersji 2.7 rozwiązuje problem. Nie wiem, która wersja jest dostarczana z OpenJDK, ale próbowałem jawnie umieścić v2.7.1 na ścieżce klas i nic się nie zmieniło. (Jak mogę sprawdzić, czy jest to faktycznie używana wersja?).

Jakiekolwiek obejścia?

Tutaj jest test z moim problemem:

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

Oto wyjątek rzucony:

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) 

Odpowiedz

5

Próbujesz analizować dokument przestrzeni nazw z non-namespace-aware parsera.

Domyślnie parsery SAX i DOM nie rozpoznają przestrzeni nazw, należy jawnie wywołać setNamespace() w fabryce. Zmień swój kod, aby wyglądał następująco i powinieneś być gotowy:

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

Wow, to było to. Komunikat o błędzie z pewnością może być jeszcze lepszy. Czasami może być tak łatwo. – yankee

Powiązane problemy