如何使用 DOM 解析器解析忽略 DOCTYPE 声明的 xhtml

How to parse a xhtml ignoring the DOCTYPE declaration using DOM parser

提问人:Rachel 提问时间:4/15/2010 更新时间:9/19/2016 访问量:9625

问:

我遇到使用 DOM 解析器解析带有 DOCTYPE 声明的 xhtml 的问题。

错误: java.io.IOException:服务器返回 HTTP 响应代码:503 for URL:http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%20

声明: DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

有没有办法将 xhtml 解析为忽略 DOCTYPE 声明的 Document 对象。

Java XML XML 解析

评论


答:

1赞 Thorbjørn Ravn Andersen 4/15/2010 #1

下载 DTD 需要解析器,但您可以通过在行上设置独立属性来绕过它。<?xml... ?>

但请注意,此特定错误很可能是由 XML 架构定义和 DTD URL 之间的混淆触发的。有关详细信息,请参阅 http://www.w3schools.com/xhtml/xhtml_dtd.asp。正确的是:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

评论

0赞 Rachel 4/15/2010
我使用了相同的 DOCTYPE。将独立 attibute 设置为“yes”时,它仍然会给出相同的错误。以下是我添加的我的xhtml:<?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ”> 我仍然收到相同的错误。java.io.IOException:服务器返回 URL 的 HTTP 响应代码:503:w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%20
1赞 Thorbjørn Ravn Andersen 4/15/2010
你有一个空间 和.dtd"
1赞 Rachel 4/15/2010
这似乎是博客中讨论的常见问题,w3.org/2005/06/blog/systeam/2008/02/08/...
1赞 David Leppik 7/28/2010 #2

最简单的方法是在 DocumentBuilderFactory 中设置 validating=false。如果要进行验证,请下载 DTD 并使用本地副本。正如上面 Rachel 所评论的,这在 WWW 联盟中进行了讨论。

简而言之,由于默认的 DocumentBuilderFactory 在每次验证时都会下载 DTD,因此每当典型的程序员尝试在 Java 中解析 XHTML 文件时,W3 都会受到打击。他们负担不起那么多的流量,所以他们以错误响应。

4赞 xpmatteo 7/30/2010 #3

一个对我有用的解决方案是给 DocumentBuilder 一个返回空流的假解析器。这里有一个很好的解释(看看 kdgregory 的最后一条消息)

http://forums.sun.com/thread.jspa?threadID=5362097

以下是 KdGregory 的解决方案:

documentBuilder.setEntityResolver(new EntityResolver()
        {
            public InputSource resolveEntity(String publicId, String systemId)
                throws SAXException, IOException
            {
                return new InputSource(new StringReader(""));
            }
        });
1赞 Djoerd 9/18/2016 #4

以下代码片段指示分析器真正忽略 DOCTYPE 声明中的外部 DTD,而不是假解析器:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

(...)

DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setValidating(false);
f.setAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder builder = f.newDocumentBuilder();
Document document = builder.parse( ... )