即使比正在衰退的DTD語法有著明顯的優勢,但W3C XML Schema (WXS)在簡潔性方面仍難以讓人稱贊。確實,在關于XML詞匯設計的討論中,DTD符號經常在單獨的白板上顯示出它快速而完整地交流
思想的能力;相應的WXS符號卻顯得可笑的笨拙,即使當WXS將要成為工具語言。因而,UML,一種圖形設計符號,對于WXS設計具有相當魅力。
UML能夠做比數據結構的簡單描述更多的事情。UML metamodel還很好地支持Schema設計,wire-serializable類型,持久schema,以及許多其他XML應用。UML和XML很可能會更頻繁地進行規范方面的接觸;如果它們能夠走到一起這將是很好的事情。應該尋找代碼設計和XML設計過程盡可能高程度的整合。
一、推行封裝
針對任何類型模式的UML應用都要求一種擴展特性。在UML和XML間有許多可能的特性和映射,但不是都指向相同的目標。OMG的XML Metadata Interchange 和XMI Production for W3C XML Schema規范提供了一個從UML/MOF到WXS為了在UML工具間交換模式的標準映射。正被討論的模型不可能確定為XML產品。WXS簡單地作為一種在一些其他工具或場所下可靠的元數據的XML描述。
我們在這主要討論這兩種元數據間的映射及改善一種支持WXS信息集完全表達的UML特性。主要的區別是XMI將UML放在首位,可以這樣說,有時候僅滿足于不能捕獲一些有用的WXS結構的映射,只要UML模型能很好地表達。我們的目標是將WXS放在第一位并發展一種在WXS設計中特定使用的UML特性:
這種特性應該能夠捕獲一個WXS能夠表達的XML詞匯的任何細節。
它應該支持WXS文檔的雙路產生。
我提出了一些stereotypes和tags,其中多數吻合XMI-Schema映射。
二、簡單類型建模
傳統的UML模式每一個目標類型模型用一個假定的原始類型集建立。在XML中,事情更復雜,即使在一個單獨的設計范圍內簡單類型也能被發明。為了支持這點,一個UML類的simpleType stereotype被使用。在這里UML規范派上了用場:一個繼承的simpleType能通過一個特定的關系鑒定它的基礎類型。
在simpleType下, 期望的約束方面可用過載UML屬性和初始化值而被建模,有利于產生一個方便性和可讀性很強的符號。即使在一個stereotype下, 盡管,屬性意味著一些實際的狀態元素,但也易被人誤解。UML約束在約束方面提供了一個更正確的符號。
自從UML為枚舉提供了一個標準stereotype,枚舉類型對于符號選擇就是一個例外。
<xs:simpleType name="Review"> <xs:restriction base="xs:decimal"> <xs:minInclusive value="0" /> <xs:maxInclusive value="5" /> <xs:pattern value="[0-5](.5)?" /> </xs:restriction> </xs:simpleType> <xs:simpleType> <xs:restriction base="xs:string" > <xs:enumeration value="G" /> <xs:enumeration value="PG" /> <xs:enumeration value="PG-13" /> <xs:enumeration value="R" /> <xs:enumeration value="NC-17" /> <xs:enumeration value="X" /> </xs:restriction> </xs:simpleType> <xs:complexType name="Movie"> <xs:sequence> <xs:element name="Title" type="xs:string" /> <xs:element name="review" type="Review" /> <xs:element name="rating" type="Rating" /> </xs:sequence> </xs:complexType> |
List和union類型有一些細微不同的問題。Unions允許值來自于被其他類型定義的一些空間的任何一個。為了建模這一點,UML使用一個{xor} 約束似乎是更清楚的表達,盡管這種結合還沒有先例被發現。List是一個更明顯的映射:它是一個參數化類型,針對模型中的任何簡單或復雜類型。
<xs:simpleType name="IntegerList"> <xs:list itemType="xs:integer" /> </xs:simpleType> <!-- Enumeration Settings not shown. --> <xs:simpleType name="OvenSetting"> <xs:union memberTypes="xs:integer Settings" /> </xs:simpleType> |
三、復雜類型建模
UML類很適合建模WXS復雜類型。UML屬性有一些輕微問題。在多數UML支持的類型模型中,只有一種途徑實現一個狀態元素,但在XML中有兩種,屬性和子元素。當狀態元素是復雜類型自己時子元素是唯一選擇,但對于單個值兩者都可選。在一些學校中,偏愛選擇僅是屬性或僅是元素,但我們的觀點是支持在兩者間選其一是十分重要的。
形式上,一個metamodel元素的規范是作為一個UML stereotype的最好說明。XMI 在" 調整" schema 生產過程中正好允許這個stereotype。這似乎顯得笨拙,但對于通用stereotype UML允許圖形化和文本化速記。
隨著XML文檔、應用程序代碼和設計討論中Xpath的流行增加,對于屬性名稱的XPath @ 前綴越來越受歡迎。它非常地簡潔,在圖形或文本表述中作為一種屬性stereotype的速記十分適合。
一個UML屬性的類型可以通過多種途徑被指定,無論是簡單或是復雜。內建的WXS類型可以通過局部名稱或使用通用名字空間前綴xs:或xsd:而被指定。同樣,composition關系能夠被描繪成UML屬性類型。
<xs:complexType name="Part"> <xs:sequence> <xs:element name="name" type="xs:string" /> <xs:element name="price" type="xs:decimal" /> </xs:sequence> <xs:attribute name="partID" type="xs:token" /> <xs:attribute name="inStock" type="xs:positiveInteger" /> </xs:complexType> |
四、關系建模
相對于WXS選項UML類間的關系能夠很好地排列成行。在UML, composition (值集合)多數不是基本關系類型,但在XML中是。Composition映射composition,集的基數映射發生的約束。角色名稱能夠被映射成期望的屬性或元素名稱;它可以利用屬性stereotype和@ prefix的優勢。
<xs:complexType name="Dealership"> <xs:sequence> <xs:element name="inventoryItem" type="Part" minOclearcase/" target="_blank" >ccurs="0" maxOccurs="unbounded" /> <!-- Other content omitted. --> </xs:sequence> </xs:complexType> |
UML 聯合對于XML是復雜的,它是分等級的基礎。XMI將聯合映射成XLinks,它是合理的但也例證了用XMI于WXS設計的一些問題,Xlinks并不在Schema詞匯之列。WXS中聯合自然映射成鍵引用。(這是Carlson的主要觀點,它將所有associations映射成compositions,混淆了值和引用聯合的區別。在schema中應該保留Associations不能作為compositions被明確建模,因此一個帶有多個引用的單獨實例在一個對象圖表中是不能多重偽造的。)
另一個困難在這出現了。核心UML能夠描述association的集基數,能從各方面給它一個名字并進行表達。它不能做的是識別在WXS中使用的selector和field部件。
這些信息實際上比面向對象更相關,并且它揭露了UML的一個主要弱點:識別鍵字段。在UML metamodel中這些信息沒有最終的歸宿——在UML中識別是絕對嚴格的——并且這些方法仍然需要指明以完成一個W3C XML Schema的產生。這能夠被指向一個tag或一個stereotype,雖然這有一些勉強,我建議一個UML屬性的鍵stereotype,經由一個簡單的速記給出。注意這可能和屬性stereotype交迭,在符號中結果如«key»@unitID。UML建模工具能夠自動完成這些stereotype間的映射并進行一個控制封裝類型的xs:key 的定義。
因此,關聯自己需要識別引用字段的順序表以產生一個xs:keyref。這能夠從角色名字的關聯繼承下來;多字段名稱可以作為一個list放進自己的名稱中,或作為一個標記值被附加。
<xs:element name="Dealership"> <xs:complexType> <xs:sequence> <!-- Referenced types Car and Salesman not shown. --> <xs:element ref="Car" minOccurs="0" maxOccurs="unbounded" /> <xs:element ref="Salesman" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> <xs:key name="SalesmanKey"> <xs:selector xpath="Salesman" /> <xs:field xpath="@sellerID" /> </xs:key> <xs:keyref name="CarToSalesman" refer="SalesmanKey"> <xs:selector xpath="Car" /> <xs:field xpath="@soldBy" /> </xs:keyref> </xs:element> |
UML association集基數的映射實際上是一個早期的XML Schema臨床論文的主要論題。
對于復雜類型UML更簡潔地映射成XML擴展類型。意味著繼承類型狀態元素被添加到基礎類型的狀態模型中。
這里唯一復雜的是XML提供了另一個復雜類型繼承的方法,即estriction。這是另一種UML stereotype的適當應用,因此我們定義約束為一個規范化的stereotype。既然這樣,繼承UML類將聲明基礎類內容模型的改變;Schema發生器將被期望在受限復雜類型中再聲明時合并這些改變到基礎類內容模型中。
五、各種各樣的Schema信息
一個關鍵問題是在哪些方面schema元素適合UML模型。這里有一些選項:或者整個模型被定向為一個schema, 或者更復雜的模型包被使用建模XML名字空間。無論怎樣都必須有一個屬性識別目標名字空間URI。
Schema元素的屬性ElementFormDefault 和 atributeFormDefault 真實地存在于UML世界觀點之外。作為目標名字空間這些必須是在同一個范圍的屬性,無論是包或是模型。
同樣,我們假定所有的內容模型都是有序的。為了建模一個選擇,使用一個{xor} UML 約束;如果你需要建模xs:all,或者一個{unordered} 約束或一個UML類將使用的單獨stereotype,former是更好的選擇。
最后的問題是在WXS中區別局部和全局類型。這確實是一個比我們認為的許多問題更普遍的問題。UML規范為一個類型在另一個內部嵌套提供了一對可能的符號,并且多數工具也有一個建立這種關系的方法。
六、方向: 行為 XML?
對于我們中間那些已發現缺乏行為模式而沮喪的人們來說,意識到對XML來說這有比數據結構更為真實的事情是一個安慰。通過一些明顯的特性,WXS可作為UML被表達,我們能夠致力于更多的前瞻性用途,特別是對于XML消息。因為對于XML的所有事物,數據從未脫離元數據。這個WSDL規范說明了XML行使編碼方法的功能,在規定的XML消息內容方面,它扮演了一個近似schema的角色。
從XML數據中心開始,WSDL描述就再一次提升到面向對象封裝級別。一個WSDL portType stereotype能夠針對整個Web服務表達語義,并且能夠成為不僅是WSDL和WXS文檔,而且是支持SOAP或HTTP消息的服務器或客戶代碼的一個復雜產生的來源。這里沒有規范被提及,但希望下面的假定能夠迎合讀者的口味:
原文轉自:http://www.anti-gravitydesign.com