解析XML时DTD的处理--解析时忽略,生成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代码
  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">   
  3. < sqlMapConfig >   
  4. < settings   useStatementNamespaces = "true" />   
  5. <!--防止空SqlMap报错 by zhangbo start -->   
  6. < sqlMap   resource = "ibatis/project/project-blank.xml" />   
  7.   
  8. < sqlMap   resource = "ibatis/project/user-mapping.xml" />   
  9. </ sqlMapConfig >   

 

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

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

 

 

Java代码
  1. public   void  addToIbatisTotleConfig() {  
  2.         try  {  
  3.             DocumentBuilderFactory factory = DocumentBuilderFactory  
  4.                     .newInstance();  
  5.               
  6.             factory.setIgnoringElementContentWhitespace(true );  
  7.             DocumentBuilder db = factory.newDocumentBuilder();            
  8.             db.setEntityResolver(new  EntityResolver(){  
  9.             public  InputSource resolveEntity(String publicId, String systemId)  throws  SAXException, IOException {                  
  10.                            if (publicId.equals( "-//iBATIS.com//DTD SQL Map Config 2.0//EN" )){  
  11.                               //这是第一种方式,即忽略DTD,新建一个默认的空XML来代替   
  12.                                return   new  InputSource( new  ByteArrayInputStream( "<?xml version='1.0' encoding='GBK'?>" .getBytes()));  
  13.                                //这是第二种方式,即指定本地的DTD文件,当然,这种方式需要把XML文件下载到本地,放入对应的目录中   
  14.                               // InputStream dtd_stream = this.getClass().getResourceAsStream("..//dtd/sql-map-config-2.dtd");   
  15.                               //    return new InputSource(dtd_stream);   
  16.   
  17.                            }                            
  18.                     return   null ;  
  19.                 }});  
  20.             String ibatisTotalConfigFileName = ctx.getIbatisTotalConfigFile();  
  21.             File ibatisTotalConfigFile = new  File(ibatisTotalConfigFileName);  
  22.             Document xmldoc = db.parse("file://localhost//" +ibatisTotalConfigFileName);  
  23.             Element root = xmldoc.getDocumentElement();  
  24.             } catch  (Exception e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.     }  
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定义时,要在转换器中操作,重点使用这个两句代码:

Java代码
  1. transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());    
  2.           transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());  
   transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());  
	            transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());

 

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

下面是我的实际应用

 

Java代码
  1. import  java.io.File;  
  2. import  java.io.FileNotFoundException;  
  3. import  java.io.FileOutputStream;  
  4.   
  5. import  javax.xml.transform.Transformer;  
  6. import  javax.xml.transform.TransformerConfigurationException;  
  7. import  javax.xml.transform.TransformerException;  
  8. import  javax.xml.transform.TransformerFactory;  
  9. import  javax.xml.transform.dom.DOMSource;  
  10. import  javax.xml.transform.stream.StreamResult;  
  11. import  javax.xml.xpath.XPath;  
  12. import  javax.xml.xpath.XPathConstants;  
  13. import  javax.xml.xpath.XPathExpressionException;  
  14. import  javax.xml.xpath.XPathFactory;  
  15.   
  16. import  org.w3c.dom.Document;  
  17. import  org.w3c.dom.Node;       
  18.   
  19.   
  20.   
  21. public   static   void  saveXml(String fileName, Document doc) { // 将Document输出到文件      
  22.             TransformerFactory transFactory = TransformerFactory.newInstance();     
  23.             try  {     
  24.                 Transformer transformer = transFactory.newTransformer();     
  25.                 transformer.setOutputProperty("indent""yes" );     
  26.         
  27.                 DOMSource source = new  DOMSource();     
  28.                 source.setNode(doc);    
  29.                 System.out.println(doc.getDoctype().getPublicId());  
  30.                    
  31.                 transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC, doc.getDoctype().getPublicId());    
  32.                 transformer.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId());  
  33.                 StreamResult result = new  StreamResult();     
  34.                 result.setOutputStream(new  FileOutputStream(fileName));     
  35.         
  36.                 transformer.transform(source, result);     
  37.             } catch  (TransformerConfigurationException e) {     
  38.                 e.printStackTrace();     
  39.             } catch  (TransformerException e) {     
  40.                 e.printStackTrace();     
  41.             } catch  (FileNotFoundException e) {     
  42.                 e.printStackTrace();     
  43.             }     
  44.         }   
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();   
	        }   
	    } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值