2013-12-09 37 views
6

我嘗試解析兩個XML文檔:<root/><root xmlns="hallo"/>。第一種情況正常,但後來的情況引發異常(xalan/xerces使用OpenJDK 1.6/1.7)。一些Google搜索表明,這是因爲使用沒有前綴的XML名稱空間。解析這樣一個文件感覺比我更爲奇特,所以我想知道如何解決這個問題。用無前綴的名稱空間解析XML:NAMESPACE_ERR

我發現報告問題的其他人在SOAP應用程序的上下文中遇到了問題,並試圖做一些複雜的工作,但我找不到任何人使用簡單的設置,例如我的。

有人建議將xalan升級到v2.7可以解決問題。我不知道OpenJDK附帶哪個版本,但我試圖明確地將v2.7.1放在類路徑上,沒有任何改變。 (我如何驗證這是實際使用的版本?)。

任何解決方法?

這裏是我的問題一個試驗:

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

這裏是拋出的異常:

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) 

回答

5

您正在嘗試解析與非命名空間感知的解析器一個命名空間的文檔。

默認情況下,SAX和DOM解析器不支持名稱空間,您需要在工廠明確呼叫setNamespace()。改變你的代碼看起來像下面,你應該很好去:

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

哇,就是這樣。錯誤消息肯定有一些改進的空間。有時它可以很容易。 – yankee