Spring的爬坑之路(五)XML的驗證模式
- DTD與XSD區別
- DTD
- XSD
- DTD與XSD總結
- 驗證模式的讀取
DTD與XSD區別
DTD
DTD ( Document Type Definition )即文擋型別定義,是一種 XML 約束模式語言,是 XML 檔案的驗證機制,屬于 XML 檔案組成的一部分, DTD 是一種保證 XML 檔案格式正確的有效 方法,可以通過比較 XML 檔案和 DTD 檔案來看檔案是否符合規范,元素和標簽使用是否正確 , 一個 DTD 檔案包含 :元素的定義規則 ,元素 間關系的定義規則 ,元素可使用 的屬性, 可使用 的物體或符號規則 ,
要使用 DTD 驗證模式的時候需要在 XML 檔案 的頭部宣告, 以下是在 Spring 中使用 DTD
宣告方式的代碼:
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE beans PUBLIC "-//Spring//DTD BEAN 2.0//EN" "http://www.Springframework.org/dtd/ Spring-beans-2.O.dtd">
<beans>
... ...
</beans>
附帶部分 spring-beans-2.0.dtd代碼:
<!ELEMENT beans (
description?,
(import | alias | bean)*
)>
<!ATTLIST beans default-lazy-init (true | false) "false">
<!ATTLIST beans default-merge (true | false) "false">
<!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
<!ATTLIST beans default-dependency-check (none | objects | simple | all) "none">
<!ATTLIST beans default-init-method CDATA #IMPLIED>
<!ATTLIST beans default-destroy-method CDATA #IMPLIED>
<!ELEMENT description (#PCDATA)>
<!ELEMENT import EMPTY>
<!ATTLIST import resource CDATA #REQUIRED>
<!ELEMENT alias EMPTY>
... ...
XSD
XML Schema 語言就是 XSD ( XML Schemas Definition ), XML Schema描述了 XML 檔案的結構, 可以用一個指定的XML Schema來驗證某個XML檔案, 以檢查該XML檔案是否符 合其要求, 檔案設計者可以通過 XMLSchema指定 XML檔案所允許的結構和內容,并可據此 檢查 XML 檔案是否是有效的 , XML Schema 本身是 XML 檔案 , 它符合 XML 語法結構 , 可以 用通用的 XML 決議器決議它 ,
在使用XML Schema 檔案對XML 實體檔案進行檢驗,除了要宣告名稱空間外 ( xmlns= http://www.Springframework.org/schema/beans),還必須通過 schemaLocation屬性來指定名稱空間所對應的 XML Schema檔案的存盤位置 , 它包含兩個部分, 一部分是名稱空間的 URI,另一部分就是該名稱空間所標識的 XML Schema 檔案位置或 URL地址( xsi:schemaLocation="http:/www.springframework.org/schema/beans http://www.
Springframework.org/schema/beans/Spring-beans.xsd ),
比如,在檔案一種,我們用到的spring.xml即為XSD模式:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="app" class="com.mycompany.app.App"></bean>
</beans>
附:Spring-beans-3.0.xsd 部分代碼如下
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/beans"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/beans">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
... ...
]]></xsd:documentation>
</xsd:annotation>
<!-- base types -->
<xsd:complexType name="identifiedType" abstract="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a bean. The scope of the identifier
is the enclosing bean factory.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a bean. A bean id may not be used more than once
within the same <beans> element.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
... ...
</xsd:schema>
DTD與XSD總結
我們只是簡單地介紹 一下 XML 檔案的驗證模式的相關知識,大致總結一下區別:
XML Schema的特點:
DTD使用是非xml語法撰寫,不支持擴展,不支持命名空間,只提供非常有限的資料型別
XML Schema的特點:
- XML Schema基于XML,沒有專門的語法
- XML Schema可以象其他XML檔案一樣決議和處理
- XML Schema比DTD提供了更豐富的資料型別.
- XML Schema提供可擴充的資料模型,
- XML Schema支持綜合命名空間
- XML Schema支持屬性組
驗證模式的讀取
了解了 DTD 與 XSD 的區別后我們再去分析 Spring 中對于驗證模式的提取就更容易理解了, 通過之前的分析(鏈接: 檔案二 doLoadBeanDefinitions方法)我們鎖定了 Spring 通過 getValidationModeForResource 方法來獲取對應資源的的驗證模式 ,
protected int getValidationModeForResource(Resource resource) {
int validationModeToUse = this.getValidationMode();
if (validationModeToUse != 1) {// 手動指定驗證模式,則使用指定驗證模式
return validationModeToUse;
} else {
// 如果為時指定則使用自動監測
int detectedMode = this.detectValidationMode(resource);
return detectedMode != 1 ? detectedMode : 3;
}
}
思路上還是比較簡單,無非是如果設定了驗證模式則使用設定的驗證模式(可以通過對呼叫 XmlBeanDefinitionReader 中的 setValidationMode 方法進行設定),否則使用自動檢測的方式 , 而自動檢測驗證模式的功能是在函式 detectValidationMode 方法中實作的,在 detectValidationMode 函式中又將向動檢測劇正模式的作業委托給了專門處理類XmlValidationModeDetector,呼叫了 XmlValidationModeDetector的 validationModeDetector方法,具體代碼如下:
XmlBeanDefinitionReader.detectValidationMode()
protected int detectValidationMode(Resource resource) {
if (resource.isOpen()) {
throw new BeanDefinitionStoreException(
"Passed-in Resource [" + resource + "] contains an open stream: " +
"cannot determine validation mode automatically. Either pass in a Resource " +
"that is able to create fresh streams, or explicitly specify the validationMode " +
"on your XmlBeanDefinitionReader instance.");
}
InputStream inputStream;
try {
inputStream = resource.getInputStream();
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Unable to determine validation mode for [" + resource + "]: cannot open InputStream. " +
"Did you attempt to load directly from a SAX InputSource without specifying the " +
"validationMode on your XmlBeanDefinitionReader instance?", ex);
}
try {
return this.validationModeDetector.detectValidationMode(inputStream);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("Unable to determine validation mode for [" +
resource + "]: an error occurred whilst reading from the InputStream.", ex);
}
}
validationModeDetector.detectValidationMode():
public int detectValidationMode(InputStream inputStream) throws IOException {
// Peek into the file to look for DOCTYPE.
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
boolean isDtdValidated = false;
String content;
while ((content = reader.readLine()) != null) {
content = consumeCommentTokens(content);
if (this.inComment || !StringUtils.hasText(content)) {
continue;
}
if (hasDoctype(content)) {
isDtdValidated = true;
break;
}
if (hasOpeningTag(content)) {
// End of meaningful data...
break;
}
}
return (isDtdValidated ? VALIDATION_DTD : VALIDATION_XSD);
}
catch (CharConversionException ex) {
// Choked on some character encoding...
// Leave the decision up to the caller.
return VALIDATION_AUTO;
}
finally {
reader.close();
}
}
hasDoctype():
/**
* Does the content contain the DTD DOCTYPE declaration?
*/
private boolean hasDoctype(String content) {
return content.contains(DOCTYPE);
}
只要我們理解了 XSD 與 DTD 的使用方法 ,理解上面的代碼應該不會太難, Spring用來檢測驗證模式的辦法就是判斷是否包含 DOCTYPE,如果包含就是 DTD,否則就是 XSD,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/203122.html
標籤:AI
上一篇:nodejs模塊和簡單爬蟲
下一篇:培訓課后作業(1)
