`

解析XML时如何处理DTD的问题

阅读更多
一般比较正式的XML信息中都会包含对应的DTD声明,用来定义该XML文档中的格式,例如WEB项目中用到的web.xml,例如struts的配置文件struts-config.xml,下面是web.xml中用到的DTD信息:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd">


当我们用DOM或者Digester来解析这个XML的时候,如果当前计算机已联网那么解析的速度比较慢,如果当前计算机未联网则会报无法连接主机的异常。这是因为XML的解析器需要读取dtd的内容,而这个dtd文件是存在于互联网的某台主机上的,因此问题就在于:如果我们的计算机不能保证时时都连在网上,那么怎么老保证解析过程不出错呢?下面我们分别就两种不同的解析方法进行说明。

1. 使用DOM解析

使用DOM解析的时候,我们可以自定义实体的解析器(EntityResolver),而不是使用默认的实体解析器,因为默认的解析器会根据实际的url进行读取,下面是一段如何来解析web.xml的代码:

private static void parse(InputStream in) throws Exception{
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  DocumentBuilder db = dbf.newDocumentBuilder();
  db.setEntityResolver(new EntityResolver(){
   public InputSource resolveEntity(String publicId, String systemId)
    throws SAXException, IOException{
          for (int i = 0; i < registrations.length; i += 2) {
           if(publicId.equals(registrations[i])){
            String dtd_uri = registrations[i+1];
               InputStream dtd_stream = this.getClass().getResourceAsStream(dtd_uri);
      return new InputSource(dtd_stream);
           }
          }
    return null;
   }});
  Document doc = db.parse(in);
  Element root = doc.getDocumentElement();
  NodeList nodes = root.getElementsByTagName("servlet-mapping");
  int nodec = nodes.getLength();
  for(int i=0;i<nodec;i++){
   Element node = (Element)nodes.item(i);
   Element servlet_name = (Element)node.getElementsByTagName("servlet-name").item(0);
   Element url_pattern = (Element)node.getElementsByTagName("url-pattern").item(0);
  
   String sn = servlet_name.getFirstChild().getNodeValue();
   String up = url_pattern.getFirstChild().getNodeValue();
   System.out.println(sn+"="+up);
  }
}

private final static String registrations[] = {
        "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
        "/web-app_2_2.dtd",
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
        "/web-app_2_3.dtd"
};



这段代码中把本来从http://java.sun.com/dtd/web-app_2_3.dtd地址中读取dtd的信息改为了从当前类路径中读取,也就是/web-app_2_3.dtd,通过重新定义InputSource来返回/web-app_2_3.dtd数据流,从而让XML解析器不从网上获取DTD信息。当然,这样做的前提是事先必须把dtd文件保存在类路径所在的目录中,以便自定义的EntityResolver可以读取到。

2. 使用Digester解析

使用Digester解析时原理也是一样的,代码有所不同而已:

Digester digester = new Digester();
digester.push(this);
digester.setNamespaceAware(true);
digester.setValidating(false);

// Register our local copy of the DTDs that we can find
for (int i = 0; i < registrations.length; i += 2) {
    URL url = this.getClass().getResource(registrations[i+1]);
    if (url != null)
        digester.register(registrations[i], url.toString());           
}



其中registrations与前一段代码相同。

通过上面两种处理办法以后,XML的解析器就不再从网上获取dtd文件,这也是为什么Tomcat包括struts项目可以在计算机没有联网下工作的原因,因为Tomcat需要解析web.xml,struts需要解析web.xml以及struts-config.xml,而这两个文件的dtd恰恰都是通过一个url给出的。

需要说明一点的是,这样做的目的并不是说屏蔽了DTD的作用,毕竟DTD是用来验证XML语法的,如果去掉了,验证的功能就没有了,因此DTD不能去掉。这样做的真正目的是在保留DTD功能外使应用程序在无网络连接的情况下也可以运行。
分享到:
评论

相关推荐

    DOM4J解析XML时DTD路径问题

    ### DOM4J解析XML时DTD路径问题 在处理XML文件时,经常需要用到DOM4J这样的库来进行解析。当XML文件包含DTD(Document Type Definition)声明时,DOM4J默认会尝试从指定的URL加载DTD文件来进行验证。这通常是为了...

    使用XmlDocumentXmlDataDocument类加载XML文件时如何忽略DTD验证

    我们可以创建一个`XmlReaderSettings`对象,设置其`XmlResolver`为`null`,并禁用DTD处理,然后使用`XmlReader.Create`方法创建一个`XmlReader`实例,最后使用这个`XmlReader`实例来加载`XmlDocument`。代码示例如下...

    jdom解析xml、dtd约束xml文件

    这是一个jdom解析xml的小例子、里面还有dtd文件的编写以及dtd文件约束xml文件。这是一个jdom解析xml的小例子、里面还有dtd文件的编写以及dtd文件约束xml文件。这是一个jdom解析xml的小例子、里面还有dtd文件的编写...

    xml语法检验DTD文件

    缺点是,它可能降低解析XML文档的性能,且限制了XML的可扩展性。 **验证工具** 为了检查XML文档是否符合DTD,可以使用XML解析器如XML Spy或编写基于DOM(Document Object Model)的验证程序。例如,`Validator....

    delphi解析xml文件实例

    本实例将详细探讨如何在Delphi 7中解析XML文件。 首先,我们需要引入必要的单元,如`Classes`和`XMLDoc`,它们包含了处理XML的基本类。`Classes`单元提供了基础的TStringList等类型,而`XMLDoc`单元则包含了...

    dtd定义xml dom4j解析xml小类

    DTD 定义 XML DOM4J 解析 XML 小类 XML 文档类型定义(DTD)是用来定义一段合法的 XML 文档块的。它用来验证你的 XML 文档是以一系列合法的元素构成的。DTD 可以在 XML 文档内部定义,也可以通过外部文件的方式引入...

    xml 解析 xml 解析几何

    解析XML主要有两种方法:DOM(Document Object Model)和SAX(Simple API for XML)。 1. DOM解析: DOM解析器将整个XML文档加载到内存中,创建一个树形结构,允许开发者通过节点遍历和操作XML数据。例如,`...

    解析XML文件(字符串)的两种方法

    在使用`SAXReader`或`DocumentHelper`解析XML时,默认情况下会验证DTD(Document Type Definition),这可能会导致解析速度变慢或者因为DTD文件不存在而抛出异常。为了提高效率和避免异常,可以通过设置解析器的相关...

    XML、DTD、Schema

    XML(可扩展标记语言,eXtensible ...了解和掌握XML、DTD和Schema,对于编写和解析符合规范的XML文档,以及确保数据的准确性和一致性至关重要。在实际开发中,根据项目需求和复杂性,选择合适的验证工具是非常重要的。

    XML DTD XSL XLD DOM

    在"XML_3_文档解析工程-老师_上.rar"和"练习解析XML_自己.rar"中,你可能有机会学习到如何使用DOM解析器读取和操作XML数据。 "Schema教程.doc"和"万维网联合会Schema示例.doc"涉及XML Schema,这是另一种比DTD更...

    xml基础(dtd约束模式,schema约束模式,xslt样式,sax解析,dom解析,jom解析)

    - 用户需要自己维护解析状态,处理事件时进行数据的积累和操作。 6. **DOM解析**: - DOM(Document Object Model)将XML文档表示为一棵树形结构,每个节点代表XML文档的一个部分。 - DOM解析器将整个XML文档...

    C++完整解析XML

    - 安全性:防止XXE(XML External Entity)攻击,避免在解析XML时加载不受信任的外部实体。 6. **实战应用** - 配置文件:XML常用于存储程序配置,C++可以方便地解析和写入这些配置。 - 数据交换:在不同系统间...

    DTD规范XML文档编写

    DTD规范XML文档编写级XML文档的一般书写格式

    dom4j解析xml详解

    ### DOM4J解析XML详解 #### 一、DOM4J简介与特性 DOM4J是一个由dom4j.org开发的开源XML解析包,专为Java平台设计,它不仅支持DOM、SAX和JAXP标准,还巧妙地融入了Java集合框架,使其成为Java开发者在处理XML数据时...

    能够解析XML的程序.rar_XML 解析_xml_解析xml

    解析XML文档的目标是将这些结构化数据转化为可操作的对象,以便程序进行进一步处理。常见的XML解析方法有两种:DOM(Document Object Model)和SAX(Simple API for XML)。 1. DOM解析:DOM将整个XML文档加载到...

    XML.rar_dtd xml_xml dtd_xml schema_xml 设计

    XML(eXtensible Markup Language)是一种...DTD和XML Schema都提供了强有力的工具,帮助我们创建结构清晰、易于理解和处理的XML数据。了解和掌握这两种方法,对于任何从事XML相关工作的IT专业人士来说都是非常重要的。

    java解析xml数据---sax解析器

    Java解析XML数据主要涉及到的是对XML文档的读取和处理,SAX(Simple API for XML)解析器是一种基于事件驱动的解析方式,适用于处理大型XML文件。与DOM(Document Object Model)解析器不同,SAX不需要一次性加载...

    XML DTD简单设计

    通过学习和理解XML DTD,开发者可以创建结构清晰、易于解析和验证的XML文档,从而提高数据交换的准确性和效率。同时,DTD也可以作为文档的元数据,帮助其他处理XML的软件理解文档的结构,提高程序的自动化处理能力。

    VTD-XML技术解析XML实例

    然而,XML文档的大小和复杂性可能导致传统DOM(Document Object Model)和SAX(Simple API for XML)解析器在处理时遇到性能问题。VTD-XML通过创建VTD索引来解决这个问题,它只需要加载部分或关键部分的XML数据到...

    三种解析XML的方法

    压缩包中的文件可能包括示例XML文件、解析XML所需的jar包以及可能的修复或处理工具。确保正确导入并引用这些jar包,以便在项目中使用XML解析功能。在遇到问题时,可以使用提供的jar包和工具进行调试和修复。

Global site tag (gtag.js) - Google Analytics