| 首页 >> 网络编程 >> XML >> XML应用 >> 新闻正文 | [字体:大 中 小] [打印文档] |
| |
|
|
XML语法 现在我们来介绍一下XML Schemas: 随着XML Schema规范的逐渐普及,它成为W3C推荐标准的那一天已经不远了。我们来看一下这个新的定义文档类型的方法。 一、定义元素 文档类型定义的工作现在大都是由DTDs来完成的,现在的DTD在功能上有一些限制,随着XML应用的越来越广泛,这些限制逐渐阻碍了XML的发展。 DTD的语法不同于XML的语法,因而需要文档编写者另外的学习一套符号语言。而软件也需要另外的一个解析器来对DTD文件进行解析。 在DTD中没有办法来定义能够从程序语言变量直接映射到XML数据的数据类型和数据格式。 没有一组被人所熟知的基本的元素以供文档编写者选择。DTDs是XML从其前辈SGML那儿继承过来的(事实上,XML本身就是一种SGML的简化版本),这个相对比较成熟的技术能够很快的让XML运行起来,并且能够让熟悉SGML的人对XML有更多的感觉。然而,很快的人们就发现,XML需要一种更具表达能力的解决方案,而不仅仅是DTD。 定义元素需要指定元素的名称、元素的内容模式、元素的属性、以及内嵌的子元素。在XML Schemas中,元素的内容模式是通过类型来定义的。一个服从于某个特定的schema的XML文档只能按照schema中定义的元素模式来编写,这同DTD的规则是一样的。元素可以是简单类型的,也可以使复杂类型的。在Schemas规范中定义了很多的简单类型,例如: string,integer和decimal。简单类型的元素不能在包含子元素和属性,而复杂类型的元素则能够嵌套子元素,并能够包含有属性。 我们来看看一个简单的定义元素的例子: <element name="quantity" type="positive-integer"/> <element name="amount" type="decimal"/> 我们知道在面向对象的观点中,有聚集和继承的概念,可以在已有的类中衍生出新类。在这儿Schema借用了这些观点,用户也可以通过聚集和继承来在老元素的基础上定义新的元素。聚集能够把一组已存在的元素组合成一个新的元素。继承则通过扩展已存在的元素来定义一个新的元素,并且这个新的元素能够代表被继承的那个元素。 比如,如果我们要从decimal类型中派生一个新的value元素,并让它有这样的内容模式:<value unit="Celsius">42</value>,我们可以这样的定义: <element name="value"> <complexType base=&single;decimal&single; derivedBy=&single;extension&single;> <attribute name=&single;unit&single; type=&single;string&single;/> </complexType> </element> 下面我们把time和value元素聚集到一个measurement元素中,形成这样的内容模式: <measurement> <time>2000-10-08 12:00:00 GMT<time/> <value unit="Celsius">42</value> 那么最终我们的schema元素定义结果就应该是这样的: <element name=&single;measurement&single; type=&single;measurement&single;/> <complexType name=&single;measurement&single;> <element name=&single;time&single; type=&single;time&single;/> <element name=&single;value&single; type=&single;value&single;/> </complexType> 和上面的schema等同DTD是: <!ELEMENT measurement (time, value)> <!ELEMENT time (#PCDATA)> <!ELEMENT value (#PCDATA)> <!ATTLIST value (unit)> 显然,它所能表达的意思就少了很多。 从Java等面向对象语言中引入的继承的特性,还包括了可以定义抽象元素来迫使实现子类元素,或者定义一个终结元素来禁止元素再被其它元素所继承。这使得从元素到Java或者C++语言的类的一一映射变得更为直观可行。二、基数表达 XML Schema比起DTD来能够更方便的表达元素基数的概念。所谓基数是指一个元素在文档中出现的次数。在DTD中,使用的是正则表达式来表示基数的,而正则表达式的表达能力在所有的形式化文法中是最低的,这使得你在定义文档的时候会遇到很多的困难。你只能够指定一次(1),零次或者更多 (*),一次或者更多 (+) 这三种基数,并用这些基数序列来构成DTD。XML Schema中则是使用minOccurs和maxOccurs这两个属性来定义元素基数,分别用来指定元素出现的最少次数和最多次数: <element ref="optionalElement" minOccurs="0"/> <element ref="twoOrMoreElements" minOccurs="2" maxOccurs="unbounded"/> <element ref="exactlyOneElement" /> minOccurs和maxOccurs的缺省值都是1,也就是说,当没有指定这两个属性的时候,元素只允许在文档中出现一次。除了这两个属性,你还可以用choice和all这两个元素。元素choice只允许它的所有子元素中的一个出现在文档中。而元素all则最为宽松,能够让其所有的子元素在文档中以任意的顺序出现任意的次数。而这些概念在DTD中都是难以表达的。 <xsd:choice> <element ref="EitherThis"/> <element ref="OrThat"/> </xsd:choice> <xsd:all> <element ref="Ying"/> <element ref="Yang"/> </xsd:all/> 三、名域 XML Schema中还支持名域。一个Schema除了可以定义XML文档词汇表外,还可以通过名域来定义目标名域,和其它可能会使用到的词汇名域。例如: <xsd:schema targetNamespace=&single;http://www.physics.com/measurements&single; xmlns:xsd=&single;http://www.w3.org/1999/XMLSchema&single; xmlns:units= &single;http://www.physics.com/units&single;> <xsd:element name=&single;units&single; type=&single;units:Units&single;/> <xsd:element name=&single;measurement&single; type=&single;measurement&single;/> <complexType name=&single;measurement&single;> <element name=&single;time&single; type=&single;time&single;/> <element name=&single;value&single; type=&single;value&single;/> </complexType> 这种机制为建立复杂的名域体系提供了一种模块化而又易于扩展的方法。使得名域的作用能够真正的被体现出来。 XML Schema提供了一个丰富而更具弹性的机制来定义XML文档词汇表。它使用XML语言本身来定义关于一个XML文档的元信息(m |
