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

问题描述:

我面临使用DOM解析器解析xhtml和DOCTYPE声明的问题。如何使用DOM解析器解析xhtml忽略DOCTYPE声明

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

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

有没有一种方法来解析XHTML Document对象忽略DOCTYPE声明。

对我而言,一个解决方案是给DocumentBuilder一个假的Resolver,它返回一个空的流。这里有一个很好的解释(看从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("")); 
      } 
     }); 

解析器是需要下载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

我使用了相同的DOCTYPE。将独立属性设置为“是”时,它仍会给出相同的错误。下面是我的我的xhtml: 我仍然得到相同的错误。 java.io.IOException:服务器返回的HTTP响应代码:503 for URL:http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%20 – Rachel 2010-04-14 20:56:04

+1

您在'.dtd'和''' – 2010-04-14 21:32:14

+1

这似乎是一个常见问题,正如博客中所讨论的那样,http://www.w3.org/2005/06/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic – Rachel 2010-04-15 01:20:42

最简单的事情就是在DocumentBuilderFactory中设置validating = false。如果您想进行验证,请下载DTD并使用本地副本。如上评论瑞秋,这是在The WWW Consortium.

总之讨论,因为默认的DocumentBuilderFactory下载DTD每次验证时,W3被击中每一个典型的程序员试图解析Java中的XHTML文件的时间。他们买不起那么多的流量,所以他们回应时有一个错误。

取而代之的是假的解析器,下面的代码片段指示解析器真的不理来自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(...)