【问题标题】:DOM Parser freezes with an HTML having a DOCTYPE declarationDOM Parser 冻结了具有 DOCTYPE 声明的 HTML
【发布时间】:2016-08-28 08:01:53
【问题描述】:

这个程序从我的站点读取两个 HTML,然后解析每个。 第一个 HTML (pass.html) 中没有 DOCTYPE 声明。 pass.html 解析正常。

第二个 HTML (freeze.html) 有一个 DOCTYPE 声明。 freeze.html 被判断为 fully valid 通过 W3C 的验证服务。 但是,当我尝试解析 freeze.html 时,程序冻结在 .parse(is)

怎么了?

import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

class DOMCallFreezes {
    public static void main(String[] args) throws Exception {
        new DOMCallFreezes().main();
    }

    void main() throws Exception {
        demo("pass.html");
        demo("freeze.html");
    }

    void demo(String htmlName) throws Exception {
        final String baseUrl = "http://x19290.appspot.com/dom-no-good/";
        URL url = new URL(baseUrl + htmlName);
        try (final InputStream is = url.openStream()) {
            final Document doc = newDocumentBuilder().parse(is);
            final DOMSource src = new DOMSource(doc);
            final StreamResult dst = new StreamResult(System.out);
            newTransformer().transform(src, dst);
        }
    }

    DocumentBuilder newDocumentBuilder() throws Exception {
        final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        return f.newDocumentBuilder();
    }

    Transformer newTransformer() throws Exception {
        final TransformerFactory f = TransformerFactory.newInstance();
        return f.newTransformer();
    }
}

pass.html

<?xml version="1.0" encoding="US-ASCII"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>pass</title>
</head>
<body>
   <h1>no DOCTYPE declaration</h1>
   </body>
</html>

冻结.html

<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>freeze</title>
</head>
<body>
    <h1>has DOCTYPE declaration</h1>
</body>
</html>

【问题讨论】:

  • 你的问题的内容必须是in你的问题,而不仅仅是链接。在问题中输入freeze.html。 (如果超过几行,请从中删除一些内容,直到您有足够小的内容来证明问题;请参阅minimal reproducible example。)
  • 您必须在 DocumentBuilder 上调用 setEntityResolver() 并提供在本地解析 DTD 的解析器。否则解析器将尝试从故意响应非常缓慢的 Web 位置下载它,从而导致您的冻结。见stackoverflow.com/questions/2640825/…

标签: java parsing dom freeze doctype


【解决方案1】:

以下设置指示解析器不要从 DOCTYPE 声明中加载外部 DTD。改方法newDocumentBuilder()

DocumentBuilder newDocumentBuilder() throws Exception {
    final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
    f.setValidating(false);
    f.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    return f.newDocumentBuilder();
}

【讨论】:

    猜你喜欢
    • 2015-07-24
    • 2018-05-13
    • 1970-01-01
    • 2012-04-26
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    相关资源
    最近更新 更多