即使比正在衰退的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" minOccurs="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消息的服务器或客户代码的一个复杂产生的来源。这里没有规范被提及,但希望下面的假定能够迎合读者的口味: