概述
- DTD与XSD的区别
- getValidationModeForResource() 分析
上一篇博客我们已经提到过,在核心逻辑方法 doLoadBeanDefinitions()
中主要是做三件事情。
- 调用
getValidationModeForResource()
获取 xml 文件的验证模式 - 调用
loadDocument()
根据 xml 文件获取相应的 Document 实例。 - 调用
registerBeanDefinitions()
注册 Bean 实例。
这篇博客主要来分析获取xml文件的验证模式
DTD与XSD的区别
了解XML文件的读者都应该知道XML文件的验证模式保证了XML文件的正确性,而比较常用的验证模式有俩种:DTD和XSD。
DTD
DTD(Document Type Definition),即文档类型定义,为 XML 文件的验证机制,属于 XML 文件中组成的一部分。DTD 是一种保证XML文档格式正确的有效验证方式,它定义了相关XML文档的元素、属性、排列方式、元素的内容类型以及元素的层次结构。其实 DTD 就相当于XML中的 “词汇”和“语法”,我们可以通过比较XML文件和DTD文件来看文档是否符合规范,元素和标签使用是否正确。
要在 Spring 中使用DTD,需要在Spring XML文件头部声明:
1 |
DTD在一定的阶段推动了XML的发展,但是它本身存在着一些缺陷:
- 它没有使用XML格式,而是自己定义了一套格式,相对解析器的重用性较差;而且 DTD 的构建和访问没有标准的编程接口,因而解析器很难简单的解析DTD文档。
- DTD对元素的类型限制较少;同时其他的约束力也叫弱。
- DTD 扩展能力较差。
- 基于正则表达式的 DTD 文档的描述能力有限。
XSD
对 DTD 的缺陷,W3C在2001年推出XSD。XSD(XML Schemas Definition)即XML Schema语言。XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。文档设计者可以通过Xml Schema指定一个XML文档所允许的结构和内容,并可据此检查一个XML文档是否有效。XML Schema 本身就是一个 XML文档,使用的是 XML 语法,因此可以很方便的解析 XSD 文档。相对于 DTD,XSD 具有如下优势:
- XML Schema基于XML,没有专门的语法
- XML Schema可以象其他XML文件一样解析和处理
- XML Schema比DTD提供了更丰富的数据类型.
- XML Schema提供可扩充的数据模型。
- XML Schema支持综合命名空间
- XML Schema支持属性组。
在使用XML Schema文档对XML示例文档进行校验,除了要声明名称空间外,还必须指定该名称空间所对应的XML Schema文档的存储位置。通过schmaLocation属性来制定名称空间所对应的XML Schema文档的存储位置,它包含俩个部分,一部分是名称空间URI,另一部分就是该名称空间所表示的XML Schema文件位置或URL地址。如果对这一块不是很懂,可以看下面这篇文章
关于XML文档的xmlns、xmlns:xsi和xsi:schemaLocation
spring配置文件中经常使用的例子
1 |
|
经过上面的介绍,你应该对xml的验证模式有了基本的了解,下面一起看spring中验证模式获取
getValidationModeForResource() 分析
1 | protected int getValidationModeForResource(Resource resource) { |
如果指定了 XML 文件的的验证模式(调用XmlBeanDefinitionReader.setValidating(boolean validating)
)则直接返回指定的验证模式,否则调用 detectValidationMode()
获取相应的验证模式,如下:
1 | protected int detectValidationMode(Resource resource) { |
前面一大堆的代码,核心在于 this.validationModeDetector.detectValidationMode(inputStream)
,validationModeDetector 定义为 XmlValidationModeDetector
,所以验证模式的获取委托给 XmlValidationModeDetector
的 detectValidationMode()
方法。
1 | public int detectValidationMode(InputStream inputStream) throws IOException { |
从代码中看,主要是通过读取 XML 文件的内容,判断内容中是否包含有DOCTYPE ,如果是则为DTD,否则为 XSD,当然只会读取到第一个<
处,因为验证模式一定会在第一个<
之前。如果当中出现了 CharConversionException
异常,则为XSD模式。
好了,XML 文件的验证模式分析完毕,下篇分析 doLoadBeanDefinitions()
的第二个步骤:获取 Document 实例。