首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Doctype作为XML文档解析XHTML文件的可怕性能

用Doctype作为XML文档解析XHTML文件的可怕性能
EN

Stack Overflow用户
提问于 2012-03-09 04:31:46
回答 2查看 2.6K关注 0票数 3

当我将这个xhtml文件解析为xml时,对这样一个简单的文件进行解析大约需要2分钟。我发现,如果删除doctype声明,它就会立即解析。是什么原因导致这个文件花了这么长的时间来解析?

Java示例

代码语言:javascript
运行
复制
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware( true );
DocumentBuilder bob = dbf.newDocumentBuilder();
Document template = bob.parse( new InputSource( new FileReader( xmlFile ) ) );

XHTML示例

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ex="http://www.example.com/schema/v1_0_0">
    <head><title>Test</title></head>
    <body>
        <h1>Test</h1>
        <p>Hello, World!</p>
        <p><ex:test>Text</ex:test></p>
    </body>
</html>

谢谢

编辑:解决方案

为了根据最初提供的关于问题发生原因的信息来实际解决问题,我执行了以下基本步骤:

EntityResolver

  • 将与DTD相关的文件下载到src/main/resources文件夹中,

  • 创建了一个自定义EntityResolver,以便从类路径中读取这些文件,

  • 告诉my DocumentBuilder使用新的EntityResolver。

在这样做的时候,我引用了这个答案:how to validate XML using java?

新EntityResolver

代码语言:javascript
运行
复制
import java.io.IOException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class LocalXhtmlDtdEntityResolver implements EntityResolver {

    /* (non-Javadoc)
     * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
     */
    @Override
    public InputSource resolveEntity( String publicId, String systemId )
            throws SAXException, IOException {
        String fileName = systemId.substring( systemId.lastIndexOf( "/" ) + 1 );    
        return new InputSource( 
                getClass().getClassLoader().getResourceAsStream( fileName ) );
    }

}

如何使用新的EntityResolver:

代码语言:javascript
运行
复制
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware( true );
DocumentBuilder bob = dbf.newDocumentBuilder();
bob.setEntityResolver( new LocalXhtmlDtdEntityResolver() );
Document template = bob.parse( new InputSource( new FileReader( xmlFile ) ) );
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-09 04:44:15

Java正在下载指定的DTD及其和包含的文件,以验证xhtml文件是否符合指定的DTD。使用Charles,我记录了使用指定数量加载的以下请求:

  • http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd - 30.4 sec
  • http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent - 30.19 sec
  • http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent - 30.23 sec
  • http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent -30.20秒
票数 3
EN

Stack Overflow用户

发布于 2012-03-09 08:36:05

实际上,你很幸运你拿到了这些文件。W3C故意对这些文档的请求没有响应,因为它们无法处理大量的请求。您需要向解析器提供本地副本。

在Java世界中,通常的方法是使用Apache/Oasis目录解析器。

最新版本的Saxon已经内置了这些常用的DTD和实体文件的知识,如果允许Saxon提供XML解析器,它将自动配置为使用本地副本。即使您没有使用XSLT或XQuery来处理数据,您也可以利用这一点:只需创建一个Saxon对象并调用其getSourceParser()方法来获取XMLReader。

(也许现在也是摆脱DOM的好时机。在Java处理XML的众多选择中,DOM可能是最糟糕的。如果您必须使用低级别的导航API,请选择一个像JDOM或XOM这样的不错的API。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9628968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档