【发布时间】: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