利用dom4j读取xml配置文件时,如果文件中出现DOCTYPE标签,可能会在read时读取异常:
Document document = reader.read(file);
导致文件读取失败,如下:
Exception in thread "main" org.dom4j.DocumentException: Error on line 1 of document http://testng.org/testng-1.0.dtd : 文档类型声明包含或指向的标记声明必须格式正确。 Nested exception: 文档类型声明包含或指向的标记声明必须格式正确。
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.dom4j.io.SAXReader.read(SAXReader.java:264)
at com.sinosoft.listest.service.impl.ProduceXmlImpl.updateAllTestngXml(ProduceXmlImpl.java:32)
at com.sinosoft.listest.service.ProduceXml.updateAllTestngXml(ProduceXml.java:16)
at com.sinosoft.listest.utils.PrepareDateUtil.updateAllTestngXml(PrepareDateUtil.java:38)
at com.sinosoft.listest.Test.main(Test.java:12)
Nested exception:
org.xml.sax.SAXParseException; systemId: http://testng.org/testng-1.0.dtd; lineNumber: 1; columnNumber: 3; 文档类型声明包含或指向的标记声明必须格式正确。
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:441)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:368)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1436)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2002)
at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:305)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1177)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1050)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:964)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at org.dom4j.io.SAXReader.read(SAXReader.java:465)
at org.dom4j.io.SAXReader.read(SAXReader.java:264)
at com.sinosoft.listest.service.impl.ProduceXmlImpl.updateAllTestngXml(ProduceXmlImpl.java:32)
at com.sinosoft.listest.service.ProduceXml.updateAllTestngXml(ProduceXml.java:16)
at com.sinosoft.listest.utils.PrepareDateUtil.updateAllTestngXml(PrepareDateUtil.java:38)
at com.sinosoft.listest.Test.main(Test.java:12)
Process finished with exit code 1
特别是testng.xml时,如果不添加则无法正常运行程序。
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
百度实验了各种解决方案都无法解决,最后终于找到了一种适用的忽略dtd文件的方法(查询的另外几种统统未解决),贴上解决的代码以供参考:
//获得文件
File file = new File(filePath);
//利用dom4j读取xml
SAXReader reader = new SAXReader();
//忽略dtd文件校验!!!
reader.setValidation(false);
reader.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
}
});
完美解决,以供参考谢谢。