一、解析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。
分享到:
相关推荐
在处理XML文件时,经常需要用到DOM4J这样的库来进行解析。当XML文件包含DTD(Document Type Definition)声明时,DOM4J默认会尝试从指定的URL加载DTD文件来进行验证。这通常是为了确保XML文件符合预定的结构和规则。...
Java解析XML数据主要涉及到的是对XML文档的读取和处理,SAX(Simple API for XML)解析器是一种基于事件驱动的解析方式,适用于处理大型XML文件。与DOM(Document Object Model)解析器不同,SAX不需要一次性加载...
值得注意的是,如果XML文件较大或者结构复杂,可能需要使用更高级的解析策略,例如错误处理、XPath查询或SAX解析。但基本的DOM解析方法已经能够处理大部分常见需求。 在实际应用中,可能还需要关注XML编码、命名...
在实际应用中,`mybatis-3-config.dtd` 和 `mybatis-3-mapper.dtd` 通过引入机制被引用到XML配置文件中,确保解析器能够理解并验证配置文件的语法。例如: ```xml <!DOCTYPE configuration PUBLIC "-//mybatis.org...
在C++环境中处理XML文件时,我们通常会依赖于专门的解析库,比如Xerces-C++。Xerces-C++ 3.0.1是这样一个开源的XML解析库,它为开发者提供了全面的XML处理能力,包括解析、验证和生成XML文档。 Xerces-C++库的核心...
这是一个jdom解析xml的小例子、里面还有dtd文件的编写以及dtd文件约束xml文件。这是一个jdom解析xml的小例子、里面还有dtd文件的编写以及dtd文件约束xml文件。这是一个jdom解析xml的小例子、里面还有dtd文件的编写...
在处理XML文件时,有时我们可能会遇到由于XML文档包含了对外部DTD(Document Type Definition)的引用,导致在使用`XmlDocument`或`XmlDataDocument`类加载文件时出现验证异常。DTD是XML的一个组成部分,用于定义XML...
- XML Grammar解析器:用于处理DTD(Document Type Definition)和XML Schema。 - XML Pipeline:允许开发者构建和组合XML处理阶段,如验证、转换等。 - Namespace和XML信息集支持:提供了对XML命名空间和信息集的...
- **外部DTD**:DTD作为单独的文件存在,并通过XML文档中的DOCTYPE声明来引用。适用于大型项目或多个文档共享相同的DTD规则的情况。 #### 五、DTD的声明 DTD声明总是以`<!DOCTYPE>`开头,后跟根元素的名称。内部...
当编写配置文件或映射文件时,遵循这两个DTD的规则,可以确保XML解析器能正确解析文件,避免因语法错误导致的运行时异常。同时,了解这些元素的含义和用法,有助于更高效地利用MyBatis进行数据库操作,提高代码的...
#### dom4j解析XML时忽略DTD文件验证 在使用`SAXReader`或`DocumentHelper`解析XML时,默认情况下会验证DTD(Document Type Definition),这可能会导致解析速度变慢或者因为DTD文件不存在而抛出异常。为了提高效率...
在处理XML文件时,通常需要借助解析库来读取、解析和操作XML文档。其中,libxml是一个功能强大的开源XML解析库,由GNOME项目开发,支持多种操作系统,包括Linux、Windows和Mac OS等。 libxml库提供了多种API,使得...
在提供的压缩包中,有两个主要文件:“xml-commons-resolver-1.1.jar”是实际的库文件,包含了所有必要的类和方法,使得开发者可以在他们的项目中集成XML Commons Resolver的功能。另一个文件“xml-commons-resolver...