`

解析XML时DTD的处理--解析时忽略,生成XML文件时加上。-- XML进阶

阅读更多

一、解析XML文件时,遇到DTD的定义要怎么办?

 

    下面这段代码是ibatis配置文件,用w3c Dom(其实任意一种解析方式都是这样)都会从http://www.ibatis.com/dtd/sql-map-config-2.dtd 这个地址找对应的DTD文件进行校验,如果因特网上这个地址不存在的话,就会报 java.net.ConnectException: Connection timed out: connect  。

 

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings useStatementNamespaces="true"/>
<!--防止空SqlMap报错 by zhangbo start -->
<sqlMap resource="ibatis/project/project-blank.xml"/>

<sqlMap resource="ibatis/project/user-mapping.xml"/>
</sqlMapConfig>

 

   遇到这种问题可以有两种解析方式,第一把DTD下载的本地,指定从本地加载DTD文件;另一种,干脆忽略DTD文件。

这两种方式都是以重新构建实体的解析器(EntityResolver)为基础解决方案的,重新构建实体解析器而不是使用默认的实体解析器,因为默认的解析器会根据实际的url进行读取,下面是一段如何来解析上面提到的配置文件,两种方式都有标注

 

 

public void addToIbatisTotleConfig() {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			
			factory.setIgnoringElementContentWhitespace(true);
			DocumentBuilder db = factory.newDocumentBuilder();			
			db.setEntityResolver(new EntityResolver(){
			public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {				 
				           if(publicId.equals("-//iBATIS.com//DTD SQL Map Config 2.0//EN")){
				        	  //这是第一种方式,即忽略DTD,新建一个默认的空XML来代替
				        	   return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='GBK'?>".getBytes()));
				        	   //这是第二种方式,即指定本地的DTD文件,当然,这种方式需要把XML文件下载到本地,放入对应的目录中
				        	  // InputStream dtd_stream = this.getClass().getResourceAsStream("..//dtd/sql-map-config-2.dtd");
				        	  //    return new InputSource(dtd_stream);

				           }				          
					return null;
				}});
			String ibatisTotalConfigFileName = ctx.getIbatisTotalConfigFile();
			File ibatisTotalConfigFile = new File(ibatisTotalConfigFileName);
			Document xmldoc = db.parse("file://localhost//"+ibatisTotalConfigFileName);
			Element root = xmldoc.getDocumentElement();
			} catch (Exception e) {
			e.printStackTrace();
		}
	}

 

 

二、使用W3CDom编辑完上面的XML文件,把document转换为XML文件的时候,DTD定义会丢失,如果要加上,要怎么办?

       加DTD定义时,要在转换器中操作,重点使用这个两句代码:

   transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());  
	            transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());

 

DTD定义的值在document对象中是有的,你可以直接输出,也可以改变。

下面是我的实际应用

 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;	 



public static void saveXml(String fileName, Document doc) {// 将Document输出到文件   
	        TransformerFactory transFactory = TransformerFactory.newInstance();   
	        try {   
	            Transformer transformer = transFactory.newTransformer();   
	            transformer.setOutputProperty("indent", "yes");   
	  
	            DOMSource source = new DOMSource();   
	            source.setNode(doc);  
	            System.out.println(doc.getDoctype().getPublicId());
	             
	            transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());  
	            transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());
	            StreamResult result = new StreamResult();   
	            result.setOutputStream(new FileOutputStream(fileName));   
	  
	            transformer.transform(source, result);   
	        } catch (TransformerConfigurationException e) {   
	            e.printStackTrace();   
	        } catch (TransformerException e) {   
	            e.printStackTrace();   
	        } catch (FileNotFoundException e) {   
	            e.printStackTrace();   
	        }   
	    } 

 

三、用w3c dom 解析带有DTD定义的XML时,会给一些元素自动加些一默认属性,例如:下面Spring的代码:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="no" default-dependency-check="none"
	default-lazy-init="false">
	<bean autowire="default"
		class="org.springframework.context.support.ClassPathXmlApplicationContext"
		dependency-check="default" id="galaxyBaseContext" lazy-init="true">
		<constructor-arg>
			<list>
				<value>spring/base-context.xml</value>
			</list>
		</constructor-arg>
	</bean>
	<bean autowire="default"
		class="org.springframework.context.support.ClassPathXmlApplicationContext"
		dependency-check="default" id="galaxyContext" lazy-init="true">
		<constructor-arg>
			<list>

 

default-autowire="no" default-dependency-check="none" default-lazy-init="false" 这三个属性是自动加的,其实我只是用W3c Dom解析后改变了一个bean元素的属性值,但是解析完,bean都会加前面三个属性,很麻烦,也可以用第一种方法解决,设置DTD忽略,忽略以后并不会影响第二点讲的解析完增加DTD。

3
0
分享到:
评论
2 楼 田智伟 2012-07-31  
貌似这篇文章有段时间了,不过最近遇到类似的问题,还没搞定,这个东西这么指定ibatis使用自动以的xml解析器,而不采用默认的呢?
1 楼 liangrockman 2010-03-05  
谢谢您的分享~~~~~~~~

相关推荐

    DOM4J解析XML时DTD路径问题

    在处理XML文件时,经常需要用到DOM4J这样的库来进行解析。当XML文件包含DTD(Document Type Definition)声明时,DOM4J默认会尝试从指定的URL加载DTD文件来进行验证。这通常是为了确保XML文件符合预定的结构和规则。...

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

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

    delphi解析xml文件实例

    值得注意的是,如果XML文件较大或者结构复杂,可能需要使用更高级的解析策略,例如错误处理、XPath查询或SAX解析。但基本的DOM解析方法已经能够处理大部分常见需求。 在实际应用中,可能还需要关注XML编码、命名...

    mybatis-3-config.dtd mybatis-3-mapper.dtd

    在实际应用中,`mybatis-3-config.dtd` 和 `mybatis-3-mapper.dtd` 通过引入机制被引用到XML配置文件中,确保解析器能够理解并验证配置文件的语法。例如: ```xml &lt;!DOCTYPE configuration PUBLIC "-//mybatis.org...

    xml解析库xerces-c-3.0.1

    在C++环境中处理XML文件时,我们通常会依赖于专门的解析库,比如Xerces-C++。Xerces-C++ 3.0.1是这样一个开源的XML解析库,它为开发者提供了全面的XML处理能力,包括解析、验证和生成XML文档。 Xerces-C++库的核心...

    jdom解析xml、dtd约束xml文件

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

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

    在处理XML文件时,有时我们可能会遇到由于XML文档包含了对外部DTD(Document Type Definition)的引用,导致在使用`XmlDocument`或`XmlDataDocument`类加载文件时出现验证异常。DTD是XML的一个组成部分,用于定义XML...

    Java解析xml的包--xerces.jar 用于开发xml相关的内空的包..zip

    - XML Grammar解析器:用于处理DTD(Document Type Definition)和XML Schema。 - XML Pipeline:允许开发者构建和组合XML处理阶段,如验证、转换等。 - Namespace和XML信息集支持:提供了对XML命名空间和信息集的...

    xml与DTD,xml与DTD

    - **外部DTD**:DTD作为单独的文件存在,并通过XML文档中的DOCTYPE声明来引用。适用于大型项目或多个文档共享相同的DTD规则的情况。 #### 五、DTD的声明 DTD声明总是以`&lt;!DOCTYPE&gt;`开头,后跟根元素的名称。内部...

    mybatis两个重要的dtd文件 batis-3-config.dtd mybatis-3-mapper.dtd

    当编写配置文件或映射文件时,遵循这两个DTD的规则,可以确保XML解析器能正确解析文件,避免因语法错误导致的运行时异常。同时,了解这些元素的含义和用法,有助于更高效地利用MyBatis进行数据库操作,提高代码的...

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

    #### dom4j解析XML时忽略DTD文件验证 在使用`SAXReader`或`DocumentHelper`解析XML时,默认情况下会验证DTD(Document Type Definition),这可能会导致解析速度变慢或者因为DTD文件不存在而抛出异常。为了提高效率...

    XML文件的解析--libxml库函数解释

    在处理XML文件时,通常需要借助解析库来读取、解析和操作XML文档。其中,libxml是一个功能强大的开源XML解析库,由GNOME项目开发,支持多种操作系统,包括Linux、Windows和Mac OS等。 libxml库提供了多种API,使得...

    xml-commons-resolver-1.1

    在提供的压缩包中,有两个主要文件:“xml-commons-resolver-1.1.jar”是实际的库文件,包含了所有必要的类和方法,使得开发者可以在他们的项目中集成XML Commons Resolver的功能。另一个文件“xml-commons-resolver...

Global site tag (gtag.js) - Google Analytics