现在的位置: 首页 > 综合 > 正文

理解XML Schema: XML Schema初步 (五)

2013年10月24日 ⁄ 综合 ⁄ 共 3133字 ⁄ 字号 评论关闭

十一从简单类型到复合类型

 

 

让我们首先考虑一下,如何声明包含了一个属性,同时拥有简单类型值的元素。在一个实例文档中,此类的元素就像下面的形式: <internationalPrice currency="EUR">423.46</internationalPrice>

 

让我们从购买订单模式文档中的USPrice元素声明开始: <xsd:element name="USPrice" type="decimal"/>

 

现在我们如何为这个元素定义添加一个属性呢? 我们以前说过,简单类型不能有属性,而decimal是简单类型。因此,我们必须定义一个复合类型来携带属性声明。然而,同时我们也想具有简单类型decimal的元素内容。所以我们最初的问题转化为:我们如何定义一个基于简单类型decimal的复合类型? 答案是,从简单类型decimal中引出一个新的复合类型(参见下图)。

 

<xsd:element name="internationalPrice">

  <xsd:complexType>

   <xsd:simpleContent>

    <xsd:extension base="xsd:decimal">

     <xsd:attribute name="currency" type="xsd:string"/>

    </xsd:extension>

   </xsd:simpleContent>

  </xsd:complexType>

 </xsd:element>

 

 

 

我们使用complexType 元素来开始定义一个新的(匿名的)类型。为了表示新类型的内容模型只包括字符数据而没有元素,我们使用simpleContent元素来实施定义。最后,我们通过扩展简单的decimal类型引出新的类型。扩展包括使用标准属性声明来添加一个currency属性。

 

 

十二混合内容

 

 

购买订单模式文档的构造也许会被特征化为元素包含子元素、并且最深的子元素包含字符数据。当然,XML Schema也为模式文档的构造提供了另一类支持:字符数据可以和子元素同时出现,也就是说字符数据并不是被限制在最深的元素中。

 

为了显示这点,考虑下面的这个使用XML表示的客户信笺的片断,该片断包含了一些购买订单相同的元素(参见下图)。

 

<letterBody>

<salutation>Dear Mr.<name>Robert Smith</name>.</salutation>

Your order of <quantity>1</quantity> <productName>Baby

Monitor</productName> shipped from our warehouse on

<shipDate>1999-05-21</shipDate>. ....

</letterBody>

 

 

 

请注意在元素之间的文本和他们的子元素。在这里,文本出现在元素salutation、quantity、productName和shipDate之间,这些元素都是LetterBody的子元素。并且在letterBody孙子元素name旁边也有文本出现。

 

<xsd:element name="letterBody">

 <xsd:complexType mixed="true">

  <xsd:sequence>

   <xsd:element name="salutation">

    <xsd:complexType mixed="true">

     <xsd:sequence>

      <xsd:element name="name" type="xsd:string"/>

     </xsd:sequence>

    </xsd:complexType>

   </xsd:element>

   <xsd:element name="quantity"    type="xsd:positiveInteger"/>

   <xsd:element name="productName" type="xsd:string"/>

   <xsd:element name="shipDate"    type="xsd:date" minOccurs="0"/>

   <!-- etc. -->

  </xsd:sequence>

 </xsd:complexType>

</xsd:element>

 

 

 

出现在客户信笺中的元素是使用我们先前看到的element 和complexType元素构造来声明的,他们的类型也是用这种方法定义的(参见上图)。

 

注意到在XML Schema中,混合模型与XML 1.0的混合模型有着根本的区别。在XML Schema下面的混合模型,子元素在一个实例中出现的顺序和数量必须与子元素在模型中说明的顺序和数量一致。与之相对,在XML1.0混合模型下,出现在实例中的子元素的顺序和数量不能被限制。总而言之,XML Schema提供了充分的混合模型的校验而XML1.0只提供了部分的模式校验。

 

十三空内容

 

 

现在假设我们想让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,这是一个默认的速记方法,所以这个简洁的语法可以在模式处理器中工作。

抱歉!评论已关闭.