java - 使用本地 DTD 验证 XML,引发错误

标签 java xml dom dtd saxparser

我正在尝试使用本地 DTD 验证我的 XML,我对此进行了谷歌搜索,然后我得到了一些代码,这是我的代码。

public Document buildDocument(File receivedFile) {
    Document doc = null;
    try {
        logger.info("Inside buildDocument() , create a new DocumentBuilderFactory");
        // create a new DocumentBuilderFactory
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        // use the factory to create a documentbuilder
        DocumentBuilder builder = factory.newDocumentBuilder();
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                System.err.println("fatalError: " + exception);
            }

            @Override
            public void error(SAXParseException exception) throws SAXException {
                System.err.println("error: " + exception);
            }

            @Override
            public void warning(SAXParseException exception) throws SAXException {
                System.err.println("warning: " + exception);
            }
        });

        builder.setEntityResolver(new EntityResolver() {
            @Override
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                if (systemId.contains("xyz.com/remote.dtd")) {
                    return new InputSource(FileUtils.readFileToString(
                            new File("C:\\Users\\xyz\\local.dtd"));
                } else {
                    return null;
                }
            }
        });
        doc = builder.parse(new InputSource(new StringReader(FileUtils.readFileToString(receivedFile, "UTF-16"))));
    } catch (ParserConfigurationException | SAXException | IOException e) {
        logger.warn("Opps got error while buiding document", e);
    }
    return doc;

我收到以下错误,我确信本地 DTD 可以与我尝试验证的 XML 正常配合。我没有发现 DTD 存在任何问题,但仍然收到此错误,请对此提供帮助。

> java.net.MalformedURLException: no protocol: <!DOCTYPE ichicsr [
> <!ENTITY lt     "&#38;#60;">
> 
> <!-- Greater Than ">" --> <!ENTITY gt     "&#62;"> 
> 
> <!-- Ampersand "&" --> <!ENTITY amp    "&#38;#38;">

然后打印整个 DTD!

at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:964)
    at org.apache.xerces.impl.XMLEntityManager.startEntity(XMLEntityManager.java:902)
    at org.apache.xerces.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:869)
    at org.apache.xerces.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:241)
    at org.apache.xerces.impl.XMLDocumentScannerImpl$DTDDispatcher.dispatch(XMLDocumentScannerImpl.java:1001)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:324)
    at org.apache.xerces.parsers.XML11Configuration.parse(XML11Configuration.java:875)
    at org.apache.xerces.parsers.XML11Configuration.parse(XML11Configuration.java:798)
    at org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:108)
    at org.apache.xerces.parsers.DOMParser.parse(DOMParser.java:230)

NOTE : My XML is encoded type UTF-16

更新:在读取文件时删除了 UF-16,看起来 DTD 正在尝试编译并且抛出以下错误,

latin-entities.dtd (The system cannot find the path specified)

这是否意味着此 DTD 正在寻找依赖 DTD?

最佳答案

我猜问题出在这里:

if (systemId.contains("xyz.com/remote.dtd")) {
    return new InputSource(FileUtils.readFileToString(
                     new File("C:\\Users\\xyz\\local.dtd"));

假设FileUtils.readFileToString()返回文件内容作为 字符串。

XMLEntityManager 期望 InputSource 提供系统 ID 作为 URL,但它会获取文件内容,因此会出现 MalformedURLException。

根据文件的 URL 创建一个 InputSource

new InputSource(new File(...).toURI().toASCIIString()

或者在文件内容上使用 StringReader 创建 InputSource

new InputSource(new StringReader(FileUtils....))

关于java - 使用本地 DTD 验证 XML,引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51579857/

相关文章:

Java 泛型类型转换,如 <String, String> 到 <Object, Object>

java - 线程调度 - 按设定顺序运行线程

java - 按钮单击方法如何找出在 ListView 中选择了哪个项目?

sql - 在 SQL 中,如何形成 XML 输出,其中属性值之一为 XML,无需 <,> 编码

c# - 在 Windows Phone 上检测流或字节数组编码

javascript - Selenium 。按类查找元素并使用 JS 将其从 DOM 中删除

Angular 2/4 - 从 DOM 中删除组件,但保留在内存中

java - Java中对象的监视器是什么意思?为什么要用这个词?

javascript - 字符在textarea中的绝对位置

php - XML 生成 PHP 脚本使用 foreach 循环将来自三列表的节点元素之间的错误列值的文本放入