扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年9月22日
关键字:
在本页阅读全文(共7页)
空内容
现在假设我们想让internationalPrice元素用属性值来传送流通的单位和价格,而不是象先前用一个属性值以及元素内容值来表示。举例来说: <internationalPrice currency="EUR" value="423.46"/>
这样的元素根本没有内容,他的内容模型是空。为了定义内容是空的类型,我们可以通过这样的方式:首先我们定义一个元素,它只能包含子元素而不能包含元素内容,然后我们又不定义任何子元素,依靠这样的方式,我们就能够定义出内容模型为空的元素。
<xsd:element name="internationalPrice">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
在上图这个例子中,我们定义了一个匿名类型,它包含的是complexContent,即只包含子元素。ComplexContent元素表明我们想要限制或者扩展一个复合类型的内容模型,并且类型为anyType的restriction元素声明了两个属性,而没有引入任何元素内容。使用这种方法声明的InternationalPrice元素就得以像上面例子里所显示的那样合理地出现在实例文档中。
前述上图中的关于空内容元素的语法相对有点冗长。我们可以通过更简洁的声明方式来声明internationalPrice元素(参见下图)。
<xsd:element name="internationalPrice">
<xsd:complexType>
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:complexType>
</xsd:element>
因为一个不带有simpleContent 或者complexContent的复合类型定义,会被解释为带有类型定义为anyType的complexContent,这是一个默认的速记方法,所以这个简洁的语法可以在模式处理器中工作。
anyType
anyType表示一个称为ur-type的抽象,它是导出所有简单类型和复合类型的基类型。一个anyType类型不以任何形式约束其包含的内容。我们可以象使用其他类型一样,使用anyType,如: <xsd:element name="anything" type="xsd:anyType"/>
用这个方式声明的元素是不受约束的。所以元素的值可以为423.46,也可以为任何其他的字符序列,或者甚至是字符和元素的混合。实际上,anyType是默认类型,所以上面的可以被重写为:<xsd:element name="anything"/>
如果需要表示不受约束的元素内容,举例来说在元素包含散文,其中可能需要嵌入标签来支持国际化的表示,那么默认的声明(无约束)或者有些微约束的形式会很合适。
注释
为了方便其他读者和应用来理解模式文档,XML Schema提供了三个元素用来注释。在购买订单模式文档中,我们在documentation元素中放置了一个基本的模式描述和版权信息,这是放置适合人阅读的信息的推荐位置。我们推荐你在任何的documentation元素中使用xml:lang属性来表示这些描述信息使用的语言。另一个替代的方式是,你可以通过在schema元素中放置xml:lang属性来指明语言信息。
我们并没有在购买订单模式文档中使用元素appInfo,这个元素能够用来为工具、样式表和其他应用提供信息。在XML Schema Part 2:Datatypes中有一个描述简单类型的模式文档,它就是一个使用appInfo很有趣的例子。documentation和 appInfo是作为annotation元素的子元素出现的,这个元素自己出现在大多数schema构造的开头。为了显示这点,下面的例子显示了如何在元素声明开头使用annotation元素声明,这是一个复合类型的定义(参见下图)。
<xsd:element name="internationalPrice">
<xsd:annotation>
<xsd:documentation xml:lang="en">
element declared with anonymous type
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:annotation>
<xsd:documentation xml:lang="en">
empty anonymous type with 2 attributes
</xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
annotation元素也会出现在其他模式构造的开头,如那些通过元素schema、simpleType和attribute来展示的模式构造。
构造内容模型
在购买订单模式文档中复合类型的定义都是定义了一系列的元素,这些元素在实例文档中都必须出现。在这些类型的内容模型中,单个元素的是否出现是可选的,这我们可以通过属性值"minOccurs=0'(如在comment中)来实现。当然我们也可以通过对minOccurs和maxOccurs赋予不同的值来实施其他不同的约束限制。XML Schema也支持对在内容模型中出现的元素组的约束。我们需要注意的是,约束是不能应用在属性声明上的。XML Schema允许定义和命名元素组。所以元素能够用来建立复合类型的内容模型,未命名的元素组也能够和命名的元素组一起被定义。他们能够被约束为他们以声明中的相同顺序序列在实例文档中出现。或者,他们能够被约束为只有一个元素可以出现在实例文档里面。
为了显示这点,我们在购买订单模式文档中的purchaseOrderType定义中引入两个元素组定义。这样,购买订单就可以有两种选择来描述地址:第一种是包含彼此独立的送货地址和收款地址,第二种情况则是仅包含一个简单的地址,这个地址即是送货地址也是收款地址(参见下图)。
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="shipAndBill"/>
<xsd:element name="singleUSAddress" type="USAddress"/>
</xsd:choice>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:group name="shipAndBill">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
</xsd:sequence>
</xsd:group>
对于choice组元素而言,在实例中仅仅允许出现这个组中的一个子内容。对于上图中的例子而言,第一个子内容是一个内部group元素,引用以shipAndBill命名的元素组,这个元素组由元素序列shipTo、billTo组成。第二个子内容为singleUSAddress.因此,在一个实例文档中,purchaseOrder元素必须,要么包含一个billTo元素和一个shipTo元素,要么包含一个singleUSAddress元素。choice组后面跟着的是comment和items元素声明。元素和组的声明都是sequence 组的子内容。这样定义的效果是comment和items元素必须按顺序跟在地址元素后面。
现在有第三种选择在组中包含元素:通过使用all元素定义的元素组,在组中所有的元素都可以出现一次或者更本不出现,而且他们能够以任何顺序出现。all组被限制放在任何内容模型的顶部,此外,all元素组的子内容必须都为独立元素(不能有组元素),在all元素定义的内容模型中的元素都不可以出现超过一次,也就是说minOccurs 和maxOccurs允许的值为"0"和"1".举例来说,为了允许purchaseOrder的子元素以任意的顺序出现,我们能够用下面的形式重新定义purchaseOrderType(参见下图):
<xsd:complexType name="purchaseOrderType">
<xsd:all>
<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:all>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者