使用XML Schema定义元素的基础

XML Schema比DTD更强大。 为了说明XML Schema机制的强大功能,前三个清单简要地比较了表示元素的不同方式。 清单1显示了XML文档的摘录。 清单2显示了用DTD语法声明的这两个元素, 清单3由相应的XML Schema语法组成。 请注意, 清单3中的语法与XML语法相同。 通过该架构,验证解析器可以验证元素InvoiceNo是正整数,并且元素ProductID由A和Z之间的一个字母以及六个数字组成。 相比之下,引用DTD的验证解析器只能验证这些元素是否表示为字符串。

清单1:一个XML文档片段
<InvoiceNo>123456789</InvoiceNo>
<ProductID>J123456</ProductID>
清单2:描述清单1中元素的DTD片段
<!ELEMENT InvoiceNo (#PCDATA)>
<!ELEMENT ProductID (#PCDATA)>
清单3:描述清单1中元素的XML模式片段
<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ProductCode'/>
<simpleType name='ProductCode' base='string'>
  <pattern value='[A-Z]{1}d{6}'/>
</simpleType>

在XML模式中使用名称空间

在协作世界中,一个人可能正在处理来自许多其他各方的文档,而不同的各方可能希望以不同的方式表示其数据元素。 此外,在单个文档中,他们可能需要分别引用由不同方创建的具有相同名称的元素。 您如何区分具有相同名称的不同定义? XML Schema允许使用命名空间的概念来区分定义。

给定的XML模式定义了一组新名称,例如元素,类型,属性,属性组的名称,其定义和声明都写在模式中。 清单3将名称定义为InvoiceNoProductIDProductCode

架构中定义的名称据说属于其目标名称空间 。 名称空间本身具有固定但任意的名称,必须遵循URL语法。 例如,您可以将清单3中摘录的模式的名称空间的名称设置为: http://www.SampleStore.com/Account : http://www.SampleStore.com/Account

名称空间名称的语法可能会令人困惑。 即使名称空间名称以http://开头,它也不会引用该URL上包含架构定义的文件。 实际上,URL http://www.SampleStore.com/Account根本不引用任何文件,仅引用分配的名称。

模式中的定义和声明可以引用可能属于其他名称空间的名称。 在本文中,我们将这些名称空间称为源名称空间 。 每个模式都有一个目标名称空间,可能还有许多源名称空间。 实际上,给定架构中的每个名称都属于某个命名空间。 名称空间的名称可能很长,但是可以使用XML Schema文档中的xmlns声明的语法缩写。 我们可以向清单4所示的示例架构中添加更多内容,以说明这些概念。

清单4:目标和源名称空间
<!--XML Schema fragment in file schema1.xsd-->
<xsd:schema targetNamespace='http://www.SampleStore.com/Account'
      xmlns:xsd='http://www.w3.org/1999/XMLSchema'
      xmlns:ACC= 'http://www.SampleStore.com/Account'>
<xsd:element name='InvoiceNo' type='xsd:positive-integer'/>
<xsd:element name='ProductID' type='ACC:ProductCode'/>
<xsd:simpleType name='ProductCode' base='xsd:string'>
  <xsd:pattern value='[A-Z]{1}d{6}'/>
</xsd:simpleType>

清单4的XML模式中, targetNamespace名称为http://www.SampleStore.com/Account,其中包含名称InvoiceNoProductIDProductCode 。 名称schemaelementsimpleTypepatternstringpositive-integer属于源名称空间http://www.w3.org/1999/XMLSchema ,在xmlns声明中缩写为xsd 。 别名xsd没有什么特别的; 我们可以选择任何名称。 为了方便起见,在本文的其余部分中,我们使用xsd引用名称空间http://www.w3.org/1999/XMLSchema并且在某些代码段中省略了xsd限定。 在此示例中, targetNamespace也恰好是源名称空间之一,因为名称ProductCode用于定义其他名称。

图1:清单4的命名空间
图1:清单4的命名空间

清单4中的模式片段不需要指定源模式文件的位置。 对于整体的“模式架构”, http://www.w3.org/1999/XMLSchema ,您无需指定位置,因为它是众所周知的。 对于源名称空间http://www.SampleStore.com/Account ,您无需指定位置,因为它也恰好是此文件中定义的目标名称空间的名称。 为了更好地理解如何指定模式位置并使用默认名称空间,请考虑清单5中示例的扩展。

清单5:多个源名称空间,导入一个名称空间
<!--XML Schema fragment in file schema1.xsd-->
<schema targetNamespace='http://www.SampleStore.com/Account'
      xmlns='http://www.w3.org/1999/XMLSchema'
      xmlns:ACC= 'http://www.SampleStore.com/Account'
      xmlns:PART= 'http://www.PartnerStore.com/PartsCatalog'>
<import namespace='http://www.PartnerStore.com/PartsCatalog'
        schemaLocation='http://www.ProductStandards.org/repository/alpha.xsd'/>
<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ACC:ProductCode'/>
<simpleType name='ProductCode' base='string'>
  <pattern value='[A-Z]{1}d{6}'/>
</simpleType>
<element name='stickyGlue' type='PART:SuperGlueType'/>

清单5还提供了另一个名称空间参考: http://www.PartnerStore.com/PartsCatalog : http://www.PartnerStore.com/PartsCatalog 。 该名称空间不同于targetNamespace和标准名称空间。 因此,必须使用import声明元素导入该元素,该元素的schemaLocation属性指定包含该模式的文件的位置。 默认名称空间是http://www.w3.org/1999/XMLSchema,xmlns声明没有名称。 每个不合格的名称(例如schemaelement属于默认名称空间http://www.w3.org/1999/XMLSchema 。 如果您的架构从一个名称空间引用了多个名称,则将其指定为默认名称空间更为方便。

XML实例文档可以引用来自在多个模式中定义的多个名称空间的元素的名称。 要引用并缩写名称空间的名称,请再次使用xmlns声明。 我们使用XML Schema实例名称空间中的schemaLocation属性来指定文件位置。 请注意,此属性不同于前面示例中xsd命名空间的相同命名属性schemaLocation

清单6:使用来自多个模式的多个名称空间名称
<?xml version="1.0"?>
<ACC:rootElement xmlns:ACC='http://www.SampleStore.com/Account'
      xmlns:PART='http://www.PartnerStore.com/PartsCatalog'
      xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
      xsi:schemaLocation='http://www.PartnerStore.com/PartsCatalog
                          http://www.ProductStandards.org/repository/alpha.xsd
                          http://www.SampleStore.com/Account
                          http://www.SampleStore.com/repository/schema1.xsd'>
<ACC:InvoiceNo>123456789</ACC:InvoiceNo>
图2:清单5和清单6的命名空间
图2:清单5和清单6的命名空间

定义元素

定义元素就是定义其名称和内容模型。 在XML Schema中,元素的内容模型由其类型定义。 然后,XML文档中的实例元素只能具有适合其架构中定义的类型的值。

类型可以是简单的或复杂的。 简单类型的值不能包含元素或属性。 复杂类型可以产生将元素嵌入其他元素的效果,也可以将属性与元素相关联。 (到目前为止,本文中的示例都是用户定义的简单类型(请参见ProductCode ))。 XML Schema规范还包括预定义的简单类型(请参见侧栏“ 简单类型” )。 派生的简单类型约束其基本类型的值。 例如,派生的简单类型ProductCode的值是基本类型string的值的子集。

简单的非嵌套元素具有简单的类型

可以将不包含属性或其他元素的元素定义为预定义或用户定义的简单类型,例如stringintegerdecimaltimeProductCode等。

清单7:元素的一些简单类型
<element name='age' type='integer'/>
<element name='price' type='decimal'/>

具有属性的元素必须具有复杂的类型

现在,尝试将属性currency添加到清单7中的简单元素price 。 你不能 简单类型的元素不能具有属性。 如果要添加属性,则必须将price定义为复杂类型。 在清单8的示例中,我们定义了所谓的匿名类型 ,其中没有为复杂类型指定显式名称。 换句话说,没有定义complexType元素的name属性。

清单8:复杂元素类型
<element name='price'>
  <complexType base='decimal' derivedBy='extension'>
    <attribute name='currency' type='string'/>
  </complexType>
</element>
<!-- In XML instance document, we can write: <price currency='US'>45.50</price> -->

嵌入其他元素的元素必须具有复杂的类型

在XML文档中,一个元素可以嵌入其他元素。 此要求直接在DTD中表达。 XML Schema定义了一个具有类型的元素,该类型可以具有其他元素和属性的声明。 有关简单示例,请参见表1

表1:DTD和XML模式中复杂数据类型的比较

XML文件
<Book>
   <Title>Cool XML<Title>
   <Author>Cool Guy</Author>
</Book>
DTD
<Book>
   <Title>Cool XML<Title>
   <Author>Cool Guy</Author>
</Book>
XML模式
<Book>
   <Title>Cool XML<Title>
   <Author>Cool Guy</Author>
</Book>
<!ELEMENT Book (Title, Author)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Author (#PCDATA)>
<element name='Book' type='BookType'/>
<complexType name='BookType'>
    <element name='Title' type='string'/>
    <element name='Author' type='string'/>
</complexType>

尽管表1中的XML代码同时符合DTD和XML Schema片段,但是它们之间还是有很大的区别。 在DTD中,所有元素都是全局元素,而表中的XML模式允许在本地定义TitleAuthor -仅在元素Book 。 为了精确地复制XML Schema中DTD声明的效果,元素TitleAuthor必须具有全局范围,如清单9所示 。 element elementref属性允许您引用先前声明的元素。

清单9:用全局简单类型定义的复杂类型
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book' type='BookType'/>
<complexType name='BookType'>
   <element ref='Title'/>
   <element ref='Author'/>
</complexType>

表1清单9的示例中, BookType是全局的,可用于声明其他元素。 相比之下, 清单10将类型本地化为Book元素的定义,并使其匿名。 请注意, 表1中的XML文档片段与表1, 清单9清单10中的所有三个模式片段匹配。

清单10:将BookType隐藏为本地类型
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
   <complexType>
      <element ref='Title'/>
      <element ref='Author'/>
   </complexType>
</element>

表达对元素的复杂约束

对于表示元素的内容模型的约束,XML Schema比DTD提供更大的灵活性。 在最简单的级别上(如DTD中一样),您可以将属性与元素声明相关联,并指示给定元素集中只有一个(1),零个或多个(*)或一个或多个(+)元素的序列可能发生在其中。 您可以使用例如element element minOccursmaxOccurs属性以及choicegroupall元素来表示XML Schema中的其他约束。

清单11:表达对元素类型的约束
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
  <complexType>
    <element ref='Title' minOccurs='0'/>
    <element ref='Author' maxOccurs='2'/>
  </complexType>
</element>

清单11中 ,在BookTitle的出现是可选的(类似于DTD'?')。 但是, 清单11还说元素Book必须至少有一位作者,但不得超过两位作者。 elementminOccursmaxOccurs的默认值为1。 元素choice仅允许其子级之一出现在实例中。 all,另一个元素表示约束,即组中的所有子元素只能出现一次或根本不出现,并且它们可以以任何顺序出现。 清单12表示TitleAuthor必须以任何顺序出现在Book中的约束,或者两者都不出现。 这种约束很难在DTD中表达。

清单12:指示必须为一个元素定义所有类型
<xsd:element name='Title' type='string'/>
<xsd:element name='Author' type='string'/>
<xsd:element name='Book'>
  <xsd:complexType>
    <xsd:all>
      <xsd:element ref='Tile'/>
      <xsd:element ref='Author'/>
    </xsd:all>
  </xsd:complexType>
</xsd:element>

超越基础

我们已经介绍了在XML Schema中定义元素所需的最基本概念,并通过简单的示例为您提供了其强大功能。 可以使用许多更强大的机制:

  • XML Schema包括对类型继承的广泛支持,从而可以重用先前定义的结构。 使用所谓的facet ,您可以派生表示一些其他类型的较小值子集的新类型,例如,通过枚举,范围或模式匹配来定义子集。 在本文的示例中,使用pattern构面定义了ProductCode类型。 子类型还可以向基本类型添加更多元素和属性声明。
  • 有几种机制可以控制是否可以完全定义子类型,或者可以在特定文档中替换子类型。 例如,可以表达InvoiceType (发票编号的类型)不能InvoiceType类型化,也就是说,没有人可以定义InvoiceType的新版本。 您还可以表示,在特定上下文中,不能替换ProductCode类型的子类型。
  • 除了子类型化之外,还可以定义等价类型,以便一种类型的值可以被另一种类型替换。
  • 通过将元素或类型声明为抽象,XML Schema提供了一种强制对其进行替换的机制。
  • 为了方便起见,可以定义和命名属性和元素组。 通过随后引用组,可以实现重用。
  • XML模式提供了三个元素appInfodocumentationannotation -用于为人类读者( documentation )和应用程序( appInfo )注释模式。
  • 您可以基于子元素的某些属性来表达唯一性约束。

通过W3C站点上的文档(请参阅参考资料 )并观看dW XML专区以获取更多信息,进一步探索XML Schema。 既然XML Schema规范已被批准前进到候选推荐标准,那么毫无疑问,越来越多的人将开始使用它。


翻译自: https://www.ibm.com/developerworks/xml/library/xml-schema/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值