成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用CAM機制提高XML驗證水平

原創
開發
本文詳細敘述了CAM即內容裝配機制(Content Assembly Mechanism)的基礎用法,優勢以及一些驗證實例。CAM是一個XML結構驗證方法,近年來開發非常迅速。它不僅是一門schema語言,其設計目的是更好地滿足業務交流和互操作性要求,它提供了強有力的機制來驗證XML結構和語義,使其簡潔、易于使用和易于維護。

【51CTO獨家特稿】CAM即內容裝配機制(Content Assembly Mechanism),它是一個XML結構驗證方法,由于它是一個新生事物,文檔很少,因此本文就當掃盲了。

XML文檔的驗證需要確認文檔是完整的,并且符合在文檔類型定義(Document Type Definition 即DTD)中指定的規則,DTD是最早的規范說明方法,它提供了有用但有限的功能來驗證XML文檔結構,但只有一點語義;接著出現了XML Schema,它提供了更多靈活性和功能,增強了對結構的支持,并且很好地支持了語義,Schematron,RelaxNG已經嘗試提升對語義的支持,但都沒有取得什么進展;現在一種全新的技術在OASIS的保護下開發出來了,它就是CAM。

CAM不僅是一門schema語言,其設計目的是更好地滿足業務交流和互操作性要求,它提供了強有力的機制來驗證XML結構和語義,使其簡潔、易于使用和易于維護;它提供了一個上下文機制 -- 一種基于XML自身其它部分或外部參數來動態調整那些應被視為有效的XML實例。

CAM是一個令人興奮的技術,它的未來充滿希望,但它是一個新技術,可能有好有壞;CAM的開發非常迅速,因此在本文中,你可能會發現很多‘在寫本文的時候’的字眼。開發團隊也很勤奮,你反饋的問題可能很快就會得到修復,而且有些問題可能你還沒有發現就已經被修復了。

因此,在寫本文的時候,CAM文檔還很潦草:有一個正式的規范,一份白皮書,一份PowerPoint演示文稿和一些簡要介紹了編輯器和API的網頁。還沒有明確的指導和教程,本文的目標就是:“CAM:缺少的手冊”,擴大CAM文檔陣營。

你需要

◆基本上熟悉XPath,CAM大量使用了Xpath定義業務規則,請參考w3School的Xpath教程溫習一下。

◆基本上熟悉XML Schema,雖然本文表面上看起來是XML Schema的繼承,因為它廣泛地依賴于與XML Schema的對比,作為最有效的溝通方法,請參考w3School的XML Schema教程溫習一下。

規定合法XML

XML文檔是元素的多層次組合,它是一個用于存儲任何數量文字或數據結構的樹狀存儲結構,XML文檔需要很好的格式,這意味著它只有一個根,其元素和屬性必須符合簡單的XML語法規則,在XML沒有映射到特定的問題域(如數學、書籍協作或金融交易)之前,它都沒什么用處,這種映射將抽象的XML區域以一種專業XML語言與你的特定問題對應起來,任何專用語義都必須事先定義好,否則就會被認為是無效的,遭到拒絕。

思考一下下面的顧客地址:

﹤address﹥
﹤address_street﹥221B Baker Street﹤/address_street﹥
. . .
﹤/address﹥

為了在XML Schema中驗證這個XML片段,你通常會定義一個如下的結構:

﹤xs:element name="address"/﹥
. . .
﹤xs:element name="address_street" type="xs:string"/﹥
. . .
﹤/xs:element﹥

這些限制條件指出﹤address_street﹥元素必須存在,并且必須包含在﹤address﹥元素內,還必須包含一個字符串。對于一個地址而言,一個簡單的字符串值可能是適當的,但其它字段你應該使用更具體的東西,要么是一個專門的字符串(一種衍生的,有限制的字符串)、日期、整數或其它定義類型。
XML Schema是一種基于語法的系統,在它里面你需要同時為語義和結構定義語法;另一方面,Schematron是一個基于規則的系統,你可以使用規則同時指定語義和結構,即你不僅使用規則指定address_street是一個字符串,還用規則指定﹤address_street﹥必須顯示在﹤address﹥元素內,XML Schema和Schematron從根本上說語義和結構都是糾纏在一起的。在編程方面耦合度很高,這是不可取的。
相比之下,CAM是一個混合系統,它將結構從語義中獨立出來(低耦合),使用規則指定語義,例如address示例看起來象:

﹤as:Structure﹥
﹤address﹥
﹤address_street﹥%street number and name%﹤/address_street﹥
. . .
﹤/address﹥
﹤/as:Structure﹥

﹤as:Rules﹥
﹤as:constraint action="datatype(//address_street,string)" /﹥
﹤/as:Rules﹥

CAM模板的﹤as:Structure﹥小節定義了XML文檔的層次結構,實際上它是從XML文檔示例復制過來的,只不過將真實數據替換成占位符(以百分號標志出來)而已,因此前面的CAM模板表示是一個使用%street number and number%占位符替換真實數據的XML實例。
﹤as:Structure﹥小節補充了部分語義,它定義了一個元素包含了哪些其他元素,以及順序,和Schematron不一樣,你不需要費力地編寫規則代碼定義結構,CAM以所見即所得的形式指定結構,而Schematron不得不自己動手寫代碼,就和使用微軟Word字處理軟件一樣方便,所見即所得形式相對使用RTF文本生成Word文檔而言,編寫RTF實在是太乏味、太困難了,而且容易犯錯,如圖1所示。

圖1
圖1

所見即所得示例,微軟Word使用更直觀的形式編輯文檔(左側),但這兩種方式實際上都在完成同一件事情
即使有一些很酷的工具如XmlSpy或Liquid XML Studio可以幫助你實現所見即所得的感覺,XML Schema也不是所見即所得的,思考一下下面的示例代碼,它定義了一個cost,范圍在1-999,保留2位小數。

﹤xs:element name="cost"﹥
﹤xs:simpleType﹥
﹤xs:restriction base="xs:decimal"﹥
﹤xs:fractionDigits value="2" /﹥
﹤xs:totalDigits value="5" /﹥
﹤xs:minInclusive value="1" /﹥
﹤xs:maxInclusive value="999" /﹥
﹤/xs:restriction﹥
﹤/xs:simpleType﹥
﹤/xs:element﹥

下面顯示的兩個CAM語法是等同的:

﹤as:constraint action="setNumberMask(//Part/cost,###.##)" /﹥
﹤as:constraint action="setNumberRange(//Part/cost,1-999)" /﹥

CAM模板的﹤as:Rules﹥小節定義了在﹤as:Structure﹥小節中明確嵌入的語義之外的所有語義,包括數據類型、約束、基數、條件等。

CAM的優勢

表1總結了相對于XML Schema和DTD,CAM的關鍵優勢,表這每行將會在本文后面介紹,或以后的文章中介紹。

表1

序號 項目 DTD XML Schema CAM 示例/注釋
1 隔離結構和業務規則  
2 當前節點固定驗證 ﹤quantity﹥將一個整數固定在1到100之間
3 當前節點條件驗證 受限的 ﹤zip﹥必須是5位數或10位數
4 跨節點條件驗證 受限的 如果﹤state﹥是FL,NV,SD,TX,WA,WY,NH或TN,﹤taxable﹥必須是no,否則就是yes
5 上下文機制 依賴于條件A或B是否符合
6 結構可變性 訂購數量超過25kg的顧客必須選擇一種物流運送方式
7 參數化引用 從加拿大采購必須符合條件x、y和z,從新西蘭訂購必須符合條件a、b和c
8 命名空間感知  
9 定義自己的數據類型 不行 可以 可以 ﹤bookNumber﹥必須是8位字符串
10 語法和文檔一樣 不行 可以 可以  
11 代碼重用 受限的 可以 可以 ﹤shipTo﹥和﹤billTo﹥地址包含相同的驗證規則
12 工具/編輯器 1  
13 圖形化設計器 使用XML Schema設計器時可以設計出復雜的結構
14 所見即所得 使用擴展框架 使用擴展框架 固有的 業務規則語句和它們執行時幾乎是一致的,真正做到了按原文所見即所得,
15 采用情況 成熟 成熟 初生嬰兒 成熟的穩定性更好,支持也多
16 API Java、Perl、Ruby、.Net Java、Perl、Ruby、.Net Java  
17 開放標準  

表 1 重要的驗證特性,DTD,XML Schema和CAM對比表

#p#

CAM編輯器介紹

從http://www.jcam.org.uk/下載最新版本的CAM編輯器,你可以選擇下載CAM模板編輯器或Jcam引擎,本文中大部分地方你只需要CAM模板編輯器就夠了(Jcam引擎執行CAM驗證)。
為了啟動CAM編輯器,你可能需要從零開始或從一個現有的XML文件或XSD文件創建一個模板,你會發現實際上創建一個模板還是瞞簡單的,我們還是使用W3C的Purchase Order模型開始,將這個文件存儲到本地,命名為po.xsd,在編輯器中,選擇‘文件’?‘從模型新建模板’,指定你剛剛存儲的文件的目錄和文件名(如圖2所示),在處理這個文件時程序可能會停頓幾秒鐘,處理完畢后,它會填滿根元素comment區域。

圖2
圖2

從模型新建模板對話框,指定你的XSD文件的路徑和文件名,然后從模型中選擇根元素,以便CAM編輯器為你創建一個基礎的CAM模板

Comment元素是po.xsd文件中所有﹤xsd:element﹥節點的第一個節點(按字母順序)的名字,這個文件包含兩個節點:comment和purchaseOrder。在下面的節選中以粗體顯示。你可以在清單1中查看完整的模型。

﹤xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"﹥

﹤xsd:annotation﹥
﹤xsd:documentation xml:lang="en"﹥
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
﹤/xsd:documentation﹥
﹤/xsd:annotation﹥

﹤xsd:element name="purchaseOrder"
type="PurchaseOrderType"/﹥

﹤xsd:element name="comment" type="xsd:string"/﹥

﹤xsd:complexType name="PurchaseOrderType"﹥
﹤xsd:sequence﹥
﹤xsd:element name="shipTo" type="USAddress"/﹥
﹤xsd:element name="billTo" type="USAddress"/﹥
﹤xsd:element ref="comment" minOccurs="0"/﹥
﹤xsd:element name="items" type="Items"/﹥
﹤/xsd:sequence﹥
﹤xsd:attribute name="orderDate" type="xsd:date"/﹥
﹤/xsd:complexType﹥

...

﹤/xsd:schema﹥

清單1 Po.xsd模型

下面是從w3c獲得了原始po.xsd模型,本文將使用它構建CAM模板:

﹤xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"﹥

﹤xsd:annotation﹥
﹤xsd:documentation xml:lang="en"﹥
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
﹤/xsd:documentation﹥
﹤/xsd:annotation﹥

﹤xsd:element name="purchaseOrder" type="PurchaseOrderType"/﹥

﹤xsd:element name="comment" type="xsd:string"/﹥

﹤xsd:complexType name="PurchaseOrderType"﹥
﹤xsd:sequence﹥
﹤xsd:element name="shipTo" type="USAddress"/﹥
﹤xsd:element name="billTo" type="USAddress"/﹥
﹤xsd:element ref="comment" minOccurs="0"/﹥
﹤xsd:element name="items" type="Items"/﹥
﹤/xsd:sequence﹥
﹤xsd:attribute name="orderDate" type="xsd:date"/﹥
﹤/xsd:complexType﹥


﹤xsd:complexType name="USAddress"﹥
﹤xsd:sequence﹥
﹤xsd:element name="name" type="xsd:string"/﹥
﹤xsd:element name="street" type="xsd:string"/﹥
﹤xsd:element name="city" type="xsd:string"/﹥
﹤xsd:element name="state" type="xsd:string"/﹥
﹤xsd:element name="zip" type="xsd:decimal"/﹥
﹤/xsd:sequence﹥
﹤xsd:attribute name="country" type="xsd:NMTOKEN"
fixed="US"/﹥
﹤/xsd:complexType﹥

﹤xsd:complexType name="Items"﹥
﹤xsd:sequence﹥
﹤xsd:element name="item" minOccurs="0" maxOccurs="unbounded"﹥
﹤xsd:complexType﹥
﹤xsd:sequence﹥
﹤xsd:element name="productName" type="xsd:string"/﹥
﹤xsd:element name="quantity"﹥
﹤xsd:simpleType﹥
﹤xsd:restriction base="xsd:positiveInteger"﹥
﹤xsd:maxExclusive value="100"/﹥
﹤/xsd:restriction﹥
﹤/xsd:simpleType﹥
﹤/xsd:element﹥
﹤xsd:element name="USPrice" type="xsd:decimal"/﹥
﹤xsd:element ref="comment" minOccurs="0"/﹥
﹤xsd:element name="shipDate" type="xsd:date" minOccurs="0"/﹥
﹤/xsd:sequence﹥
﹤xsd:attribute name="partNum" type="SKU" use="required"/﹥
﹤/xsd:complexType﹥
﹤/xsd:element﹥
﹤/xsd:sequence﹥
﹤/xsd:complexType﹥

﹤!-- Stock Keeping Unit, a code for identifying products --﹥
﹤xsd:simpleType name="SKU"﹥
﹤xsd:restriction base="xsd:string"﹥
﹤xsd:pattern value="\d{3}-[A-Z]{2}"/﹥
﹤/xsd:restriction﹥
﹤/xsd:simpleType﹥

﹤/xsd:schema﹥

你實際上想要purchaseOrder作為根,因此在對話框中將根元素切換成purchaseOrder,然后點擊‘確定’生成模板,此時程序會提示你保存模板,保存后模板就在CAM模板編輯器中打開了,如圖3所示:

圖3
圖3

CAM編輯器,從po.xsd模型生成模板后,編輯器同時顯示了結構和規則

編輯器中的每個標簽容器都涉及到一個視圖,結構視圖以樹形結構顯示XML的層次,圖3顯示定單有一個orderData屬性和四個子節點:shipTo,billTo,comment和items。items節點可能包括多個item子節點。CAM編輯器精確地反映了基礎XML CAM模板文件(PurchaseOrder/purchaseOrder_from_schema.cam),如下所示,這個文件中的﹤as:AssemblyStructure﹥小節顯示的內容實際上與圖3中結構視圖中的信息是一致的:

﹤as:AssemblyStructure﹥
﹤as:Structure taxonomy="XML" ID="purchaseOrder" reference=""﹥
﹤purchaseOrder orderDate="%YYYY-MM-DDZ%"﹥
﹤shipTo country="US"﹥
﹤name﹥%string%﹤/name﹥
﹤street﹥%string%﹤/street﹥
﹤city﹥%string%﹤/city﹥
﹤state﹥%string%﹤/state﹥
﹤zip﹥%54321.00%﹤/zip﹥
﹤/shipTo﹥
﹤billTo country="US"﹥
﹤name﹥%string%﹤/name﹥
﹤street﹥%string%﹤/street﹥
﹤city﹥%string%﹤/city﹥
﹤state﹥%string%﹤/state﹥
﹤zip﹥%54321.00%﹤/zip﹥
﹤/billTo﹥
﹤comment﹥%string%﹤/comment﹥
﹤items﹥
﹤item partNum="%string%"﹥
﹤productName﹥%string%﹤/productName﹥
﹤quantity﹥%1%﹤/quantity﹥
﹤USPrice﹥%54321.00%﹤/USPrice﹥
﹤comment﹥%string%﹤/comment﹥
﹤shipDate﹥%YYYY-MM-DDZ%﹤/shipDate﹥
﹤/item﹥
﹤/items﹥
﹤/purchaseOrder﹥
﹤/as:Structure﹥
﹤/as:AssemblyStructure﹥

相比之下,XSD文件混合了結構和業務規則,因此維護成本更高,下面是一個完整CAM文件的頂層框架,顯示了兩個主要的元素:

﹤as:CAM
xmlns:as="http://www.oasis-open.org/committees/cam"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:camed="http://jcam.org.uk/editor"
CAMlevel="1"
version="1.0"﹥
﹤as:Header /﹥
﹤as:AssemblyStructure /﹥
﹤as:BusinessUseContext /﹥
﹤/as:CAM﹥

你可以在清單2中查看完整的CAM模板文件。

清單2 生成的CAM模板

從原始XML模型文件生成的purchaseOrder_from_schema.cam模板:

﹤as:CAM xmlns:as="http://www.oasis-open.org/committees/cam"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:camed="http://jcam.org.uk/editor" CAMlevel="1" version="1.0"﹥
﹤as:Header﹥
﹤as:Description﹥Generated for : purchaseOrder﹤/as:Description﹥
﹤as:Owner﹥To be Completed﹤/as:Owner﹥
﹤as:Version﹥0.1 generator v1.18﹤/as:Version﹥
﹤as:DateTime﹥2008-12-08T12:31:34﹤/as:DateTime﹥
﹤/as:Header﹥
﹤as:AssemblyStructure﹥
﹤as:Structure taxonomy="XML" ID="purchaseOrder" reference=""﹥
﹤purchaseOrder orderDate="%YYYY-MM-DDZ%"﹥
﹤shipTo country="US"﹥
﹤name﹥%string%﹤/name﹥
﹤street﹥%string%﹤/street﹥
﹤city﹥%string%﹤/city﹥
﹤state﹥%string%﹤/state﹥
﹤zip﹥%54321.00%﹤/zip﹥
﹤/shipTo﹥
﹤billTo country="US"﹥
﹤name﹥%string%﹤/name﹥
﹤street﹥%string%﹤/street﹥
﹤city﹥%string%﹤/city﹥
﹤state﹥%string%﹤/state﹥
﹤zip﹥%54321.00%﹤/zip﹥
﹤/billTo﹥
﹤comment﹥%string%﹤/comment﹥
﹤items﹥
﹤item partNum="%string%"﹥
﹤productName﹥%string%﹤/productName﹥
﹤quantity﹥%1%﹤/quantity﹥
﹤USPrice﹥%54321.00%﹤/USPrice﹥
﹤comment﹥%string%﹤/comment﹥
﹤shipDate﹥%YYYY-MM-DDZ%﹤/shipDate﹥
﹤/item﹥
﹤/items﹥
﹤/purchaseOrder﹥
﹤/as:Structure﹥
﹤/as:AssemblyStructure﹥
﹤as:BusinessUseContext﹥
﹤as:Rules﹥
﹤as:default﹥
﹤as:context﹥
﹤as:constraint action="makeOptional(//purchaseOrder/@orderDate)" /﹥
﹤as:constraint condition="string-length(.) ﹤11"
action="setDateMask(//purchaseOrder/@orderDate,YYYY-MM-DD)" /﹥
﹤as:constraint condition="string-length(.) ﹥10"
action="setDateMask(//purchaseOrder/@orderDate,YYYY-MM-DDZ)" /﹥
﹤as:constraint action="makeOptional(//shipTo/@country)" /﹥
﹤as:constraint action="datatype(//shipTo/@country,NMTOKEN)" /﹥
﹤as:constraint action="setNumberMask(//shipTo/zip,######.##)" /﹥
﹤as:constraint action="makeOptional(//billTo/@country)" /﹥
﹤as:constraint action="datatype(//billTo/@country,NMTOKEN)" /﹥
﹤as:constraint action="setNumberMask(//billTo/zip,######.##)" /﹥
﹤as:constraint action="makeOptional(//purchaseOrder/comment)" /﹥
﹤as:constraint action="makeRepeatable(//items/item)" /﹥
﹤as:constraint action="makeOptional(//items/item)" /﹥
﹤as:constraint action="setNumberMask(//item/quantity,######)" /﹥
﹤as:constraint action="setNumberRange(//item/quantity,1-999999)" /﹥
﹤as:constraint action="setNumberMask(//item/USPrice,######.##)" /﹥
﹤as:constraint action="makeOptional(//item/comment)" /﹥
﹤as:constraint action="makeOptional(//item/shipDate)" /﹥
﹤as:constraint condition="string-length(.) ﹤11"
action="setDateMask(//item/shipDate,YYYY-MM-DD)" /﹥
﹤as:constraint condition="string-length(.) ﹥10"
action="setDateMask(//item/shipDate,YYYY-MM-DDZ)" /﹥
﹤/as:context﹥
﹤/as:default﹥
﹤/as:Rules﹥
﹤/as:BusinessUseContext﹥
﹤/as:CAM﹥

規則視圖(圖3中高亮顯示)顯示了所有的業務規則,組成了模板的語義,與結構不同,規則存儲在文件中時與規則視圖不一樣,表2將規則視圖中的規則集中在一起了,在沒有研究這些規則的詳細情況時,你可以從它們發現:

◆規則可能是有條件的或絕對的,例如orderDate依賴于它的長度格式要求改變。

◆項目和條件是通過XPath指定的,在CAM中會廣泛使用到XPath,它提供了極大的靈活性和清晰度,相比之下,XML Schema 1.0只為高級的xs:unique和xs:key concepts使用XPath。

◆規則可能適用于很廣的元素范圍,也可能只能適用于很少的元素,XPath支持選擇文檔的中任何一部分:一個元素、一個屬性、所有你給定名稱的元素、所有在樹中確定位置的元素等。

◆規則是壓縮的、簡潔的、非常直觀的。實際上,正如你將會看到的,編寫CAM規則和編寫應用程序需求是一樣的。

條件 項目 行為
  //purchaseOrder/@orderDate makeOptional()
string-length(.) ﹤ 11 //purchaseOrder/@orderDate setDateMask(YYYY-MM-DD)
string-length(.) ﹥ 10 //purchaseOrder/@orderDate setDateMask(YYYY-MM-DDZ)
  //shipTo/@country makeOptional()
  //shipTo/@country datatype(NMTOKEN)
  //shipTo/zip setNumberMask(######.##)
  //billTo/@country makeOptional()
  //billTo/@country datatype(NMTOKEN)
  //billTo/zip setNumberMask(######.##)
  //purchaseOrder/comment makeOptional()
  //items/item makeRepeatable()
  //items/item makeOptional()
  //item/quantity setNumberMask(######)
  //item/quantity setNumberRange(1-999999)
  //item/USPrice setNumberMask(######.##)
  //item/comment makeOptional()
  //item/shipDate makeOptional()
string-length(.) ﹤ 11 //item/shipDate setDateMask(YYYY-MM-DD)
string-length(.) ﹥ 10 //item/shipDate setDateMask(YYYY-MM-DDZ)

表 2 編輯器中的業務規則:為定單轉換XML Schema,讓CAM自動生成這些規則。

#p#

CAM驗證示例

現在你可以使用手中的模板驗證XML文件,W3C網站上除了提供定單模型外,還提供了一個定單實例(PurchaseOrder/po.xml),但下載下來的會有一個印刷錯誤,圖4高亮顯示了錯誤,如果你嘗試打開或驗證畸形的XML文件,CAM編輯器會顯示堆棧轉儲信息和錯誤消息(也看圖4),并拒絕載入文件。

圖4
圖4

畸形XML文件:這個圖顯示了為什么原始的po.xml文件不是合適的,將其載入CAM編輯器時顯示出其錯誤

當你通過將感嘆號和左半邊尖括號對換位置修復這個錯誤后(正確的文件是PurchaseOrder/po_corrected.xml),你可以使用CAM編輯器載入這個XML文件,CAM編輯器以XML視圖形式顯示這個文件,繪制成如結構視圖那樣的樹狀結構,如圖5所示,目前在模板中相同的元素顯示的是真實的值而不是占位符。

圖5
圖5

XML視圖:當你打開一個XML文件時,以XML視圖形式顯示樹形結構,可以折疊和展開

為了驗證文檔,選擇‘運行’?‘運行JCam’,你將會看到如圖6所示的Jcam運行對話框,默認情況下,Jcam選擇載入的XML文件,應該可以通過它的結構ID如purchaseOrder(這個結構的根)來識別,點擊‘完成’關閉這個對話框開始驗證,結果顯示在主窗口中下方的運行結果視圖中,注意驗證過程發現了兩個錯誤,盡管在圖6中只顯示了一個,如果你仔細一看,你會發現有錯誤的節點上會有一個黃色或紅色的圖標,在本例中,錯誤發生在﹤zip﹥元素上,它的父元素﹤shipTo﹥也顯示了一個錯誤圖標,甚至根元素﹤purchaseOrder﹥也顯示了一個錯誤圖標。同樣,你可以推斷第二個錯誤是隱藏在﹤billTo﹥元素中的。

圖6
圖6

執行驗證:驗證結果顯示在運行結果視圖中,每個驗證失敗的元素或屬性都有一個錯誤標記,它的上級元素就有一個警告標記

這個XML文件在任何XML Schema編輯器中驗證都沒有錯誤,為什么在這里驗證就失敗了呢?運行結果視圖中的錯誤指出zip代碼根據CAM模板的定義是無效的,這個模板會檢查是否是一個浮點數,因為在美國zip代碼要么是5位要么是9位的整數,zip代碼的CAM模板規則來自XSD規格說明XSD規格說明簡單說明了zip代碼是一個十進制數,這一點你可以從清單1中看到:在USAddress復雜類型中查找zip字段,CAM模板生成程序應該避免不用的輸入輸出。但你可能不同意,我提交的XSD規格說明太寬松了,數據類型應該是一個整數而不是一個十進制數,下面的部分將會介紹如何使用CAM編輯器來糾正這個錯誤。

當你按照本文的例子進行研究時,你可能會遇到模板沒有象預期那樣運轉,在這種時候要檢查兩樣東西:

◆點擊‘工具’→‘驗證CAM模板’菜單項查找所有問題。

◆如果你在運行JCam對話框中點擊‘完成’按鈕,似乎什么事情都不會發生,按‘取消’關閉對話框,然后查看控制臺視圖中的錯誤消息,例如,如果你忘記指定要驗證的XML文件了,對話框不會禁用完成按鈕,控制臺視圖中報告的錯誤是‘模板是空的’,這多少會讓人有些誤解。如果控制臺視圖什么都沒有顯示,那就表示一切ok。

#p#

創建業務規則

在結構視圖中選擇﹤shipTo﹥元素下的﹤zip﹥元素,附加到這個元素的規則顯示在項目規則(ItemRules)視圖中,在本例中只有一個規則,使用的是setNumberMask謂詞。在類別(category)列中的規則上點擊右鍵打開這個規則的上下文菜單,然后選擇‘編輯規則’,打開編輯約束規則對話框,如圖7所示。

圖7
圖7

編輯約束規則:為了修復setNumberMask謂詞附加到//shipTo/zip元素,選擇結構視圖中的元素,打開它的上下文菜單,選擇編輯規則打開編輯約束規則對話框,點擊數字特征碼字段明確指定特征碼

在數字特征碼字段上點擊,打開另一個對話框編輯特征碼,現在只需要將######.##修改為#####即可,關閉這兩個對話框,在主編輯器窗口中,你會看到更新后的規則,重新執行一次驗證,//shipTo/zip錯誤應該不會再出現,只留下//billTo/zip錯誤,很明顯這是一個相同的錯誤,因此你可以使用相同的手段修復它,但因為//billTo/zip和//shipTo zip的值應該一樣,這樣就可以使用一個通用的規則而不用每個指定一條規則了,本文的第二部分將會詳細地介紹如何使用通用規則。

規則更新后你也應該更新占位符(圖7中的項目1),如果你和圖6比較,你會發現值從%54321.00%變成%54321%了,它更能代表zip代碼,在這個特殊的例子中,元素的占位符和關聯的規則的緊密相關的,假設它們自動相互跟蹤是合理的,但在許多情況下,關系并不是直接的,元素和規則是多對多的關系:你可以對一個元素應用多個規則,或者一個規則應用給多個元素。

為了更新圖7所示的元素占位符,在結構視圖中//shipTo/zip字段上打開上下文菜單,選擇‘編輯文本’,在對話框中將54321.00%修改成%54321%。

占位符為兩個角色服務,CAM處理程序單獨使用它確定某個元素的內容是否已被修復,這是由圍繞在占位符兩邊的百分比符號確定的,注意在更新元素的占位符前,你要重新驗證//shipTo/zip字段,確認在百分比符號中間的值被CAM處理程序忽略。

百分比符號之間的值應該是準確、簡明地指出包含什么元素,通常上下文已經為你完成了大部分工作:元素的名字是‘zip’,在美國它會被立即認為是5、9或10位整數,通過設置占位符為%54321%,你告訴用戶模板只接受5個字符的zip代碼。

強度測試驗證

現在你已經更新了占位符和規則,但只修改這兩個地方就足夠驗證zip代碼了嗎?為了測試它,你需要為CAM處理程序提供不同的測試用例,最簡單的方法是打開包含你要驗證的數據的XML視圖,修改//shipTo/zip的值,然后再重新驗證,你可以在XML視圖中象結構視圖那樣編輯節點:打開上下文菜單選擇編輯文本,確定最小值以便覆蓋到所有范圍,讓每個值都被驗證一次,表3提供了這樣一個列表,從這個表中可以看到有兩個地方一個是pass掉,而另一個卻沒有過,只有這兩個驗證函數都過了才行。

//shipTo/zip setNumberMask(#####) setStringMask(00000)
90952 Pass Pass
90952.1 Fail Fail
123456 Fail Fail
90952-1234 Fail Fail
1 Pass Fail
(blank entry) Fail Fail
90952a Fail Fail
-12345 Pass Fail
(123) Fail Fail

表 3 zip代碼測試用例:這個表顯示了使用數字型特征碼#####和使用字符串型特征碼00000進行驗證的結果,結果以綠色表示的是正確的,以紅色表示的是錯誤的

這兩個測試都通過具有相同的原因:特征碼是數字,這兩個測試都是有效的數字。雖然zip代碼只包含數字,實際上它是一個字符串,從數字上來說,00001和1是相等的,在zip代碼域中,00001代表一個有效的代碼,而1不是。因此要使用numeric特征碼代替textual特征碼,為//shipTo/zip打開編輯約束對話框,將行為從setNumberMask修改成setStringMask,在String Mask字段上點擊打開特征碼編輯器,輸入5個0,或者按數字0-9之間任何一個數字5次,然后退出這兩個對話框,如果你現在重新驗證表3中的每個測試用例,你會發現它們所有的測試結果都是正確的。

在正式的CAM規格說明書的3.4.3節(CAM內容特征碼語法)列出了有效的特征碼字符,表4就是改變自它的。

表 4 特征碼字符:當規則行為需要特征碼時,這些字符有特定的含義

字符 描述

字符串特征碼

X 任何字符,強制性
A 強制性字母數字字符或空格
a 非強制性字母數字字符或空格
? 任何單一字符
* 0或更多字符0
U 一個可以被轉換為大寫的字符
^ 大寫,非強制
L 一個可以被轉換為小寫的字符
_ 小寫,非強制
0 數字、后綴和前端插入的0,前端插入的正負號
# 數字、后綴和前端插入的0被取消,前端插入的正負號
' ' 轉義字符

數字型特征碼

0 數字、后綴和前端插入的0,前端插入的正負號
# 數字、后綴和取消前端插入的0,前端插入的正負號
. 小數點
J 特征碼的第一個字符,可能調用Java格式化方法處理特征碼,當傳遞給Java時,文字J被忽略

日期型特征碼

DD 一月中的某天
DDD 一年中的某天
DDDD 一月中的相對某天
MM 一年中的月份
MMM... 月名,如January(一月),字段會被填充或截斷成3-10個數字
YY 兩位數的年
YYYY 四位數的年
W 一周的某天
WWW... 期名,字段會被填充或截斷成3-10個數字
/ 斜號,日期分隔符
- 連字符,另一個日期分隔符

如果你想找一個具有完整、清晰文檔,并且所有的bug都被消除的工具,那這個可能會讓你失望,但你如果不介意寶石周圍那一點點瑕疵,我相信在你的兵器庫中CAM會是一個偉大的工具,最后,我要告訴那些熱心的開發者們,CAM編輯器和CAM引擎最近的版本(我用的是1.6.2版)中的行為完全是合理的。

這是第一部分的內容,到此就結束了,現在你至少知道其實使用CAM設計時還是很簡單的,在本文的第二部分中,你將會看到CAM的強大之處,另外,你還將會看到關于開發模板和規則使用的技術更深入的討論,包括:通用結構和通用規則,基于內部或外部因子的條件驗證,詳細比較XSD關于數據類型、排序和基數。最后還將介紹如何避免常犯的錯誤。

【編輯推薦】

  1. XML結構與語法入門詳解
  2. XML新手入門 創建構造良好的XML
  3. 使用SAXParser處理XML文檔
責任編輯:yangsai 來源: 51CTO.com
相關推薦

2017-12-12 16:43:54

SparkHadoop水平

2012-02-02 15:04:02

軟件開發

2023-07-11 10:38:24

區塊鏈文件驗證安全

2009-07-16 16:51:56

WebWork驗證機制

2012-06-21 16:19:30

程序員

2020-12-14 12:17:47

MySQL記錄語句

2009-09-16 08:44:46

學習CCNA和CCNP

2022-06-01 14:10:46

物聯網5G蜂窩技術

2022-03-24 15:11:49

區塊鏈云計算數據

2009-01-04 16:58:48

LINQ to XMLLINQXML

2010-09-07 16:34:47

DB2 XML

2010-09-09 13:15:59

提高VPN質量

2011-08-11 11:08:09

2023-12-22 15:32:20

2021-03-31 10:15:27

人工智能美國技術

2017-05-18 09:16:54

前端CSS技巧

2021-01-14 09:34:35

量子量子網絡量子通信

2020-11-08 14:32:01

JavaScript變量內存管理

2010-10-29 10:56:46

ORACLE用戶驗證

2010-01-27 15:05:58

SQLServerExchange醫療服務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色毛片在线看 | 欧美日韩毛片 | 成人午夜电影网 | 日韩精品专区在线影院重磅 | 日韩第一区 | 国产探花在线观看视频 | 日韩毛片在线视频 | 一区二区三区四区不卡视频 | 欧美综合国产精品久久丁香 | 欧美激情综合网 | 午夜激情视频 | 一级大黄| 青青草这里只有精品 | 久久亚洲国产 | 精品久久久久久久久久久下田 | 在线欧美一区 | av大片| 亚洲国产视频一区二区 | 日韩在线高清 | 欧美在线观看一区二区 | 91精品国产综合久久小仙女图片 | 亚洲视频免费播放 | 日韩www | 国产在线精品一区二区 | 国产精品免费一区二区 | 欧美成人aaa级毛片在线视频 | 91av精品| 狠狠撸在线视频 | 国产一区中文字幕 | 久久久久久国产精品久久 | 日韩欧美一区二区三区免费看 | 九九热精品视频 | 中午字幕在线观看 | 国产欧美精品一区二区色综合朱莉 | 91视频精选 | 国产高清一区二区三区 | 欧美日韩综合一区 | 国产精品一区久久久 | 欧美亚洲国产一区二区三区 | 亚洲av毛片成人精品 | 欧美久久一区 |