`

解析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  
谢谢您的分享~~~~~~~~

相关推荐

    jdom解析xml、dtd约束xml文件

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

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

    mybatis配置的重要文件包括mybatis-3-config.dtd mybatis-3-mapper.dtd

    DOM4J解析XML时DTD路径问题

    使用dom4j解析含有这样dtd的xml文件时,它会从网络找到这个文件对xml文件进行校验。但是如果电脑断开网络的话就会出现错误说找不到dtd文件并解析失败。所以请使用以下方法...

    xml与DTD,xml与DTD

    xml与DTD,xml与DTD,xml与DTD,xml与DTD

    XML-DTD实例讲解

    XML入门精解之DTD 文件格式定义(XML DTD)  DTD实际上可以看作一个或多个XML文件的模板,这些XML文件中的元素、元素的属性、元素的排列方式/顺序、元素能够包含的内容等,都必须符合DTD中的定义。XML文件中的元素,...

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

    在XML文件含有外部DTD验证的时候,使用XmlDocument/XmlDataDocument类的Load方法会抛出如下的例外: System.Xml.XmlException: 未找到所需的 DTD 标记。 行 m,位置 n。 我们可以采用下面的方法不去加载外部资源: ...

    xml-dtd文件配置

    xml-dtd文件配置

    《XML》实验(1) -- XML Basics & DTD

    2、熟悉和掌握XML规范的基本内容,包括XML声明、注释、处理指令、元素、属性、CDATA段、预定义实体、命名空间的使用,以及如何进行XML文档良构和有效性验证;能够灵活地使用XML层次数据来表示各种信息。 3、掌握如何...

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

    解析XML文件(字符串)的两种方法,dom4j解析XML时候忽略DTD文件验证

    C++ 使用TinyXML解析XML文件 源码

    C++ 使用TinyXML解析XML文件,简单清晰,仅供参考。读取和设置xml配置文件是最常用的操作,TinyXML是一个开源的解析XML的C++解析库

    使用DTD验证XML文档

    使用DTD验证XML文档 ...a) DTD使每个XML文件可以携带一个自身格式的描述。 b) DTD使不同组织的人可以使用一个通用DTD用来交换数据。 c) DTD使应用程序可以使用一个标准DTD校验从外部接收的XML数据是否有效。

    mybatis-3-config/mapper.dtd 解决mybatis头文件报错

    然后打开eclipse -&gt;Window-&gt;prefenrence-&gt;XML-&gt;XML Catalog-&gt;User Specifiled Entreis-&gt;Add-&gt;Location(此处是你放dtd文件的位置例如:‪D:\mybatis\mybatis-3-config.dtd)-&gt;Key(如果更改config,此处应该是:-//...

    XML的DTD教程

    关于XML的DTD教程,关于XML的DTD教程,关于XML的DTD教程

    web.xml详解(web-app_2_3.dtd)

    部署描述文件web.xml详解(web-app_2_3.dtd),全面介绍: 1. icon元素 2. display-name元素 3. description元素 4. distributable元素 5. context-param元素 6. filter元素 7. filter-mapping元素 8. ...

    mybatis配置xml最新dtd文件

    最新版的mybatis配置xml文件所需的dtd文件

    XML实验(1) - XML Basics & DTD

    《XML》实验任务书 (1) XML Basics & DTD [实验目的] 1、安装并学习如何使用XMLSPY集成开发环境完成XML相关的开发工作。 2、熟悉和掌握XML规范的基本内容,包括XML声明、注释、处理指令、元素、属性、CDATA段、...

    XML、DTD、Schema

    XML、DTD、Schema笔记、使用方法、注意事项,尤其是对XML和DTD比较详细

    XML实用大全----xml详细参考书

    比较全面的XML参考电子书!强列推荐。如下是目录: 第一部分 XML简介... 9 第1章 XML概览... 9 1.1 什么是XML. 10 1.1.1 XML是元标记语言... 10 1.1.2 XML描述的是结构和语义,而不是格式化... 10 1.2 为什么...

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

     好了,通过第三章的学习,我们已经了解了一些XML和DTD的基本术语,但是我们还不知道怎样来写这些文件,需要遵循什么样的语法,在下一章,将重点介绍有关撰写XML和DTD文档的语法。 第四章 XML语法 七.DTD的语法...

    mybatis-3-mapper.dtd下载

    xml--&gt;xml catalog--&gt;add--&gt;fileSystem.. 后再设置 key type--&gt;public id key--&gt;加入xml文件下的-//mybatis.org//DTD Mapper 3.0//EN OK 3、关闭你的xml文件,刷新一下,ok。可以用了。

Global site tag (gtag.js) - Google Analytics