国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
JAXP 驗證-使用 JAXP 1.3 的新功能驗證 XML
http://www-128.ibm.com/developerworks/cn/xml/x-jaxpval.html

JAXP 驗證

使用 JAXP 1.3 的新功能驗證 XML


級別: 中級

Brett McLaughlin (brett@newInstance.com), 作家/編輯, O‘Reilly Media, Inc.

2005 年 11 月 03 日

Java™編程語言的最新版本 Java 5.0 包括經(jīng)過改進和擴展的 Java API for XML Processing(JAXP)版本。JAXP主要增加了新的驗證 API,它提供了更好的交互性,支持 XML Schema 和 RELAX NG,能夠在驗證的同時即時修改。經(jīng)過這些改進,為Java 開發(fā)人員提供了一種工業(yè)強度的 XML 驗證解決方案。本文詳細介紹這種新的 API,包括基本特性和更高級的特性。

幾年來,Java API for XML Processing(JAXP)一直是一種穩(wěn)定、有點兒沉悶的API。這并不是壞事。沉悶常常意味著可靠,對軟件來說總是好事。不過 JAXP 的遲鈍已經(jīng)讓開發(fā)人員不再尋求新的特性。從 Java 1.3 到1.4,除了支持最新版本的 SAX 和 DOM 規(guī)范(請參閱 參考資料)以外,JAXP 沒有很大變化。但是在 Java 5.0 和 JAXP 1.3 中,Sun 大大擴展了 JAXP。除了支持 XPath 以外,最值得一提的還有驗證。本文詳細介紹了 JAXP 1.3 的驗證特性,該特性在 javax.xml.validation 包中實現(xiàn)。

簡要的歷史回顧

無所不在的模式

本文中(而且一般來說),模式(schema) 指的是跟隨一種 XML 格式的任何約束模型。XML Schema 是一種模式,但模式不一定是 XML Schema(按照 W3C 規(guī)范的定義)。比如,模式 也可用于 RELAX NG 模式。使用一般意義的 模式 更便于指稱某種特定的方法(基于 XML 的約束模型)而不局限于具體的實現(xiàn)。

詳細了解這種驗證 API 的具體細節(jié)之前,必須充分了解 JAXP 1.3 之前驗證是如何完成的。此外,顯然 Sun 仍將支持過去的 DTD 驗證方法,但是建議使用基于模式的新的驗證 API。因此即便您義無反顧地要使用 javax.xml.validation 包,仍然需要理解使用 DTD 驗證文檔的方法。

創(chuàng)建解析器工廠

在一般的 JAXP 處理中,都是從 工廠 開始的。SAXParserFactory 用于 SAX 解析,DocumentBuilderFactory 則用于 DOM 解析。這兩種工廠都使用靜態(tài)方法 newInstance() 創(chuàng)建,如清單 1 所示。


清單 1. 創(chuàng)建 SAXParserFactory 和 DocumentBuilderFactory
				// Create a new SAX Parser factorySAXParserFactory factory = SAXParserFactory.newInstance();// Create a new DOM Document Builder factoryDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

打開驗證

一個工廠,多個解析器

對工廠設置的選項影響該工廠創(chuàng)建的所有解析器。如果用 true 調(diào)用 setValidating(),則明確地告訴工廠創(chuàng)建的所有解析器都必須是進行驗證的。要記住,很容易出現(xiàn)這種情況:在工廠中打開驗證,在寫了 100 行代碼之后忘了這個設置,也就忘了生成的解析器是進行驗證的。

雖然 SAXParserFactoryDocumentBuilderFactory 有分別適合 SAX 和 DOM 的不同特性和性質(zhì),但是對驗證來說它們都有一個共同的方法:setValidating()。如您所料,要打開驗證,只需要把 true 傳遞給該方法。但是使用工廠是為了創(chuàng)建解析器而不是直接解析文檔。創(chuàng)建工廠之后就可以調(diào)用 newSAXParser()(SAX)或 newDocumentBuilder()(DOM)。清單 2 顯示了這兩個方法,都打開了驗證。


清單 2. 打開驗證(DTD)
				// Create a new SAX Parser factorySAXParserFactory factory = SAXParserFactory.newInstance();// Turn on validationfactory.setValidating(true);// Create a validating SAX parser instanceSAXParser parser = factory.newSAXParser();// Create a new DOM Document Builder factoryDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// Turn on validationfactory.setValidating(true);// Create a validating DOM parserDocumentBuilder builder = factory.newDocumentBuilder(); 

無論哪種情況,都將得到一個能夠解析 XML 并在解析過程中驗證 XML 的對象(SAXParserDocumentBuilder)。但是要記住,這樣做 限于 DTD 解析。setValidating(true) 調(diào)用對基于 XML 的解析完全沒有作用。





回頁首


javax.xml.validation 簡介

5年前,用一個漂亮的方法打開 DTD 驗證就足夠了。甚至兩年前,XML Schema 和 RELAX NG之類的模式語言仍然在忙于解決自己的問題。但今天,用模式驗證文檔與 DTD 方式一樣常見。這兩種方法同時存在很大程度上是因為遺留文檔仍然使用DTD。今后幾年內(nèi),DTD 將和 Lisp 一樣消失,成為歷史遺跡而不是主流技術。

JAXP 1.3 通過引入 javax.xml.validation包支持模式驗證已經(jīng)在開發(fā)人員中引起了很大反響。這個包易于使用,結構緊湊,已經(jīng)成為 Java 語言的標準組成部分。更好的是,如果您曾經(jīng)通過JAXP 使用過 SAX 和 DOM,那么掌握如何驗證就更簡單了。模型是類似的,您會發(fā)現(xiàn)使用這種 API 進行驗證簡直輕而易舉。

使用 SchemaFactory

通過 簡要的歷史回顧 您知道,使用 SAX 的第一步是創(chuàng)建新的 SAXParserFactory。如果使用 DOM 則首先創(chuàng)建 DocumentBuilderFactory。因此毫不奇怪,進行模式驗證首先要創(chuàng)建 SchemaFactory 類的實例,如清單 3 所示。


清單 3. 創(chuàng)建 SchemaFactory
				import javax.xml.XMLConstants;import javax.xml.validation.SchemaFactory;...SchemaFactory schemaFactory =      SchemaFactory.newInstance(XMLConstants.W3C_SCHEMA_NS_URI);

這和其他工廠的創(chuàng)建類似,只不過增加了傳遞給 newInstance() 方法的參數(shù)。必須向該方法傳遞另一個類中定義的常量,即 javax.xml.XMLConstants 類,對這個類也需要非常熟悉。這個類定義了 JAXP 應用程序中使用的所有常量,不過現(xiàn)在只需要知道兩個:

  • 用于 RELAX NG 模式的 XMLConstants.RELAXNG_NS_URI
  • 用于 W3C XML Schema 的 XMLConstants.W3C_XML_SCHEMA_NS_URI

因為 SchemaFactory 是與具體的約束模型聯(lián)系在一起的,所以必須在工廠構造的時候提供這個值。

SchemaFactory 類還有其他幾個選項。這些內(nèi)容在后面的 深入了解驗證 一節(jié)中再介紹。對于一般的 XML 驗證,預設的工廠就夠了。

針對模式進行驗證

Use the Source, Luke

盡管這個標題威嚴、一語雙關,其實在整個 JAXP 中 Source 接口非常重要。該接口源自 XML 轉換處理,已經(jīng)成為各種 JAXP 結構的輸入標準,至少對于沒有直接使用 Java 語言 IO 類的情況是這樣。如果從未使用過 Source 及其實現(xiàn),請看一下 參考資料 中關于 XML 轉換的文檔和文章。

建立工廠后還需要裝入需要使用的約束集??梢酝ㄟ^工廠的 newSchema() 方法來完成。但是工廠以 javax.xml.transform.Source 實現(xiàn)作為輸入,因此需要一個中間步驟:將模式轉化成 Source 表示。這個過程很簡單,如清單 4 所示。


清單 4. 從約束到 Schema
				import javax.xml.XMLConstants;import javax.xml.transform.Source;import javax.xml.transform.stream.StreamSource;import javax.xml.validation.SchemaFactory;import javax.xml.validation.Schema;...SchemaFactory schemaFactory =     SchemaFactory.newInstance(XMLConstants.W3C_SCHEMA_NS_URI);Source schemaSource =      new StreamSource(new File("constraints.xml"));Schema schema = schemaFactory.newSchema(schemaSource);			

如果熟悉 JAXP,那么這些代碼都非常直觀。清單 4 中加載了一個名為 constraints.xml 的文件??梢允褂萌魏畏椒ǖ玫?Source 中的數(shù)據(jù),包括使用 SAX 或 DOM(分別通過 SAXSourceDOMSource)讀取約束,甚至使用 URL。

一旦得到了 Source 實現(xiàn),就將其傳遞給工廠的 newSchema() 方法。返回的就是 Schema。現(xiàn)在,對文檔進行驗證就很簡單了。請參閱清單 5。


清單 5. 驗證 XML
				import javax.xml.XMLConstants;import javax.xml.transform.Source;import javax.xml.transform.stream.StreamSource;import javax.xml.validation.SchemaFactory;import javax.xml.validation.Schema;import javax.xml.validation.Validator;...SchemaFactory schemaFactory =      SchemaFactory.newInstance(XMLConstants.W3C_SCHEMA_NS_URI);Source schemaSource = new StreamSource(new File("constraints.xml"));Schema schema = schemaFactory.newSchema(schemaSource);Validator validator = schema.newValidator();validator.validate(new StreamSource("my-file.xml"));			

這里同樣沒有什么大的變化。只要知道要使用的類和調(diào)用的方法就很容易了。因為要進行驗證,所以必須使用 Validator 類。可以使用 newValidator() 方法從 Schema 得到這個類的實例。最后可以調(diào)用 validate() 并再次傳遞 Source 實現(xiàn),不過這一次它代表要解析和驗證的 XML。

調(diào)用該方法之后就會解析和驗證目標 XML。要記住,即使用 DOMSource 提供 XML(解析過的 XML 表示),解析也可能再次發(fā)生。驗證仍然和解析緊密聯(lián)系在一起,因此驗證過程需要一點兒時間。

如果出現(xiàn)錯誤,就會拋出異常說明出了問題。JAXP 的多數(shù)實現(xiàn)都包括行號,有時候還有列號,幫助定位違反約束模型的位置。當然,僅僅拋出異常并不一定是解決問題的最佳方式。我將在 下一節(jié) 介紹一種更好的方法。

看起來似乎工作不少:得到工廠,得到模式,得到驗證器。讓 JAXP 提供一個工廠方法來完成這一切是完全可能的,比方說 validate(Source schema, Source xmlDocument) 這樣的方法。但是模塊化有一定的好處,在 下一節(jié) 中將看到同時使用 SchemaValidator 類,可以解決 XML 處理中某些非常奇特的個別情況。而且如果確實需要可以自己編寫,不妨當作一個很好的練習!





回頁首


深入了解驗證

對于很多應用程序來說,上面介紹的這些內(nèi)容就足夠了。您可以把輸入文檔和模式交給一個方法讓它去驗證。簡單的 Exception 告訴您遇到了問題,甚至還提供了一些解決問題的基本信息。對于將 XML 作為數(shù)據(jù)格式的應用程序,可能僅僅是傳遞某些信息,關于 JAXP 的驗證功能可能知道這些就足夠了。

但是,我們生活在一個到處都是 XML 編輯器、文件和代碼生成器以及 Web 服務的世界中。對于這類應用程序,XML 就不僅僅起輔助作用,而 應用程序本身,基本的驗證常常就不夠了。對于這類應用程序,JAXP 提供了很多特性,這是下面要討論的。

處理錯誤

首先,人們認為 Exception 表明發(fā)生了異常的行為。但是對于基于 XML 的應用程序而言,文件驗證失敗可能根本不是異常,僅僅可能的結果之一。比方說支持 XML 的編輯器或者 IDE。在這些環(huán)境中,無效的 XML 不應該造成系統(tǒng)崩潰和關閉。另外,如果只能以 Exception 形式報告錯誤 ,就過于沉重了。

當然,對于 JAXP 老手這并不新鮮,您可能已經(jīng)習慣為 SAXParserDocumentBuilder 提供 org.xml.sax.ErrorHandler。這個接口提供的三個方法 warning()error()fatalError() 簡化了解析中的錯誤處理。幸運的是,驗證 XML 時也有相同的設施可用。更好的是,使用的還是同一個接口。正是如此,ErrorHandler 接口在驗證中與在解析中一樣有用。清單 6 提供了一個簡單的例子。


清單 6. 處理驗證錯誤
				import javax.xml.XMLConstants;import javax.xml.transform.Source;import javax.xml.transform.stream.StreamSource;import javax.xml.validation.SchemaFactory;import javax.xml.validation.Schema;import javax.xml.validation.Validator;import org.xml.sax.ErrorHandler;...SchemaFactory schemaFactory =     SchemaFactory.newInstance(XMLConstants.W3C_SCHEMA_NS_URI);Source schemaSource = new StreamSource(new File("constraints.xml"));Schema schema = schemaFactory.newSchema(schemaSource);Validator validator = schema.newValidator();ErrorHandler mySchemaErrorHandler = new MySchemaErrorHandler();validator.setErrorHandler(mySchemaErrorHandler);validator.validate(new StreamSource("my-file.xml")); 

和 SAX 一樣,可以使用該接口自定義錯誤的處理。從而讓應用程序從容地退出驗證、打印錯誤消息,甚至可以嘗試從錯誤中恢復并繼續(xù)驗證。如果熟悉這個接口,完全不需要再重新學習!

裝入多個模式

一個又一個 setErrorHandler()

如果閱讀 javax.xml.validation 包的 JavaDoc,可能會注意到 SchemaFactory 以及 Schema 類上的 setErrorHandler() 方法。如果為 SchemaFactory 設置異常處理程序,就可以處理在 newSchema() 調(diào)用過程中解析模式時出現(xiàn)的錯誤。因此這也是驗證 API 的一部分,不過不適用于模式驗證錯誤而是用于模式解析錯誤。

某些很少見的情況下,可能需要從多個模式構造 Schema 對象。這有點兒費解;一個 Schema 不是 對應一個模式或文件。相反,該對象表示一組約束。這些約束可以來一個文件,也可以來自多個文件。因此,可以通過 newSchema(Source[] sourceList)newSchema() 方法提供一個 Source 實現(xiàn)數(shù)組(表示多個約束)。返回的仍然是一個 Schema 對象,表示所提供的模式的組合。

可以預料,這種情況下會出現(xiàn)很多錯誤。因此建議為 SchemaFactory 設置 ErrorHandler(更多信息參見 處理錯誤 一節(jié))。很多地方都可能出問題,因此要準備好在出現(xiàn)的時候解決問題。

把驗證集成到解析中

到目前為止,我們一直把驗證作為獨立于解析的單獨部分。但是并非必須如此。得到 Schema 對象后,就可以將其賦給 SAXParserFactoryDocumentBuilderFactory,都通過 setSchema() 方法(參見清單 7)。


清單 7. 把驗證集成到解析中
				// Load up the documentDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// Set up an XML Schema validator, using the supplied schemaSource schemaSource = new StreamSource(new File(args[1]));SchemaFactory schemaFactory = SchemaFactory.newInstance(  XMLConstants.W3C_XML_SCHEMA_NS_URI);Schema schema = schemaFactory.newSchema(schemaSource);// Instead of explicitly validating, assign the Schema to the factoryfactory.setSchema(schema);// Parsers from this factory will automatically validate against the//   associated schemaDocumentBuilder builder = factory.newDocumentBuilder();Document doc = builder.parse(new File(args[0])); 

要注意,這里 需要使用 setValidating() 方法顯式地打開驗證。任何 Schema 不是 null 的工廠所創(chuàng)建的解析器都會使用那個 Schema 進行驗證??梢灶A料,驗證錯誤都會報告給解析器設置的 ErrorHandler。





回頁首


重要的警告

雖然看起來不錯,我認為還不夠好,JAXP 的新驗證 API 存在一些嚴重的問題。首先,即使在 Java 5.0 和 JAXP 1.3正式版中,我也發(fā)現(xiàn)有很多錯誤和奇怪的行為。新的 API仍然在增加解析器支持,這意味著個別情況(很少使用的特性)僅僅部分實現(xiàn)了(有時候根本沒有實現(xiàn))。我發(fā)現(xiàn)很多時候,能夠通過獨立驗證器如xmllint(請參閱 參考資料)驗證的文檔卻不能通過 JAXP 的驗證。

直接使用 Validator 類和 validate() 方法,與將 Schema 賦給 SAXParserFactoryDocumentBuilderFactory 相比,似乎更可靠。建議您采用比較保險的辦法。我并不是要求您避開這種 API,而是說應該使用盡可能多的樣本文檔,并對驗證結果檢查兩次,對錯誤處理要小心謹慎。





回頁首


結束語

坦白地說,JAXP 驗證 API 并沒有明顯的新東西??梢岳^續(xù)使用 SAX 或 DOM 解析和驗證 XML,并結合 SAX 的 ErrorHandler 類,通過巧妙的編程也能對驗證錯誤進行即時處理。但是這需要對 SAX 有充分的了解,需要很多時間去測試和調(diào)試并且仔細地管理內(nèi)存(如果最終創(chuàng)建 DOM Document對象的話)。這正是 JAXP 驗證 API閃光的地方。它提供了一種經(jīng)過認真測試的、可以隨時使用的解決方案,而不僅僅是是否啟用模式驗證的一個開關。它很容易與已有的 JAXP代碼結合在一起,增加模式驗證非常簡單。我相信,長期使用 XML 的 Java 開發(fā)人員一定會發(fā)現(xiàn) JAXP 驗證的一些優(yōu)點。

http://blog.csdn.net/haydenwang8287/archive/2007/09/13/1784398.aspx

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
驗證 XML 是否符合 Schema
JR - 精品文章 - Java語言的XML驗證API
Xerces問題
JAXB、JAXP、JAXM、JAX-WS
webservice API自動化測試(二)
jaxp筆記2007-4-17 - good things in life are free - 博客園
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服