XML校验
文档域
- XML文档可以看作是程序中数据结构的快照
- 它们用于程序之间的信息交流
- 这些信息都属于某个应用领域——要解决的问题空间
- DTD具有以下两个作用:将你掌握的知识提供给程序,同时获得了文件资料
验证文档的有效性
- 如果格式正规的文档是遵循一些隐式规则编写的,解析器无法根据这些规则检查其中的错误。
- 如果某个XML文档引用了DTD,验证有效性的解析器应该读取DTD,并确保文档符合DTD中描述的语法。
- 有效性验证并不能避免应用程序逻辑方面的失误,但是它能够过滤出代码中的无效数据。
编写DTD:通用原则
- 简单来说, XML文档由元素和相应的属性组成。
- DTD必须能够定义文档中的所有元素,元素可以设置的属性,以及元素之间的关系。
- 将DTD与XML文档相关联
- DTD是与文档相关的。
- DOCTYPE标记
- DOCTYPE声明包含关键字DOCTYPE、文档根元素的名称,以及内容声明结构。
- 内部DTD子集
- 外部DTD
- 基本标记声明
正式的DTD结构
实体
为了在DTD中声明实体,需要定义实体的名称及它引用的内容。
- 预定义实体:XML必须保留某些字符用于本身格式的定义;另外,有些字符是不可打印的。
- 通用实体:通用实体是最简单的实体形式。它能够声明与某个名称相关联的可解析的文本块,通过该名称引用相应的文本。这类实体声明包含关键字ENTITY、实体名称和替换值
- 参数实体:仅仅在DTD中使用的解析实体称为参数实体
- 在DTD中,所有参数实体必须在引用之前进行声明。引用参数实体时,需要在实体名称之前增加百分号,在其后增加分号。定界符与名称之间没有空格
元素
- 元素是XML的核心与灵魂。在DTD中,元素类型是通过ELEMENT标记声明的
- 元素内容可以分为以下四种类型:空、元素、复合及任意
- 内容模型即元素结构的声明。它是由圆括号包含的若干子元素名称、运算符和#PCDATA关键字的组合
- 元组运算符
- 思考以下元素各表示什么内容?
属性
- 属性是对元素的补充和修饰,它能够将一些简单的特性与元素相关联。通过属性,可以给元素绑定大量信息
- 缺省值
- CDATA
- ID 、IDREF、IDREFS:文档中的关系表示
- ENTITY、E NTITIES:可替换的内容
- NMTOKEN、NMTOKENS:名称记号
- NOTATION:非XML数据
- 枚举类型:选择
条件部分
- 条件部分包括:惊叹号、左方括号、关键字,以及由方括号包含的声明块。如果关键字为INCLUDE,其中的声明被认为是DTD的一部分。如果关键字为IGNORE,处理器虽然读取其中的声明,但是在处理时忽略它。
DTD的缺点
- 它使用自己的一套语法,与文档实例的语法截然不同
- 不能使用解析器动态创建DTD
- DTD是一种封闭的结构
- DTD在数据类型信息方面也存在一定的缺陷。它所提供的唯一工具就是表示法,无法根据现有的类型定义自己的新类型
XML Schema
XML Schema的概念
- 模式(schema)这个词语表示图解、计划或框架。在XML中,它指描述XML文档的文档。
<product effDate="2001-04-02">
<number>557</number>
<size>10</size>
</product>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="product" type="ProductType"/>
<xsd:complexType name="ProductType">
<xsd:sequence>
<xsd:element name="number" type="xsd:integer"/>
<xsd:element name="size" type="SizeType"/>
</xsd:sequence>
<xsd:attribute name="effDate" type="xsd:date"/>
</xsd:complexType>
<xsd:simpleType name="SizeType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="2"/>
<xsd:maxInclusive value="18"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
- W3C于2001年5月2日发布了W3C的最终推荐标准,标志着XML Schema经历三年多的发展终于修成正果
- Schema 是一种描述信息结构的模型,它是借用数据库中一种描述相关表格内容的机制,它为一类文件树立了一个模式,这个模式规范了文件中tag(标签)和文本可能的组合形式
<address>
<name>Namron H. Slaw</name>
<street>256 Eight Bit Lane</street>
<city>East Yahoo</city>
<state>MA</state>
<zip>12481-6326</zip>
</address>
<address>
<name>Namron H. Slaw</name>
<street>256 Eight Bit Lane</street>
<city>East Yahoo</city>
<state>MA</state>
<state>CT</state>
<zip>blue</zip>
</address>
XML Schema的新特性
- 丰富的数据类型
- 用户定义的数据类型(Archetypes)
- 属性(Attribute)分组
- 可修改的archetypes(原型)
- Namespace的支持
模式的用途
- 数据确认
- 交易双方的合约
- 系统文档
- 数据扩充
- 应用程序信息
模式设计
- 准确性和精确性
- 明晰性
- 广泛适用性
元素
Schema Component: Element Declaration
{name}
An NCName as defined by [XML-Namespaces].
{target namespace}
Either ·absent· or a namespace name, as defined in [XML- Namespaces].
{type definition}
Either a simple type definition or a complex type definition.
{scope}
Optional. Either global or a complex type definition.
{value constraint}
Optional. A pair consisting of a value and one of default, fixed.
{nillable}
A boolean.
{identity-constraint definitions}
A set of constraint definitions.
{substitution group affiliation}
Optional. A top-level element definition.
{substitution group exclusions}
A subset of {extension, restriction}.
{disallowed substitutions}
A subset of {substitution, extension, restriction}.
{abstract}
A boolean.
{annotation}
Optional. An annotation.
XML Representation Summary: element Element Information Item
<element
abstract = boolean : false
block = (#all | List of (extension | restriction |
substitution)) default = string
final = (#all | List of (extension | restriction)) fixed = string
form = (qualified | unqualified) id = ID
maxOccurs = (nonNegativeInteger | unbounded) : 1 minOccurs = nonNegativeInteger : 1
name = NCName nillable = boolean : false ref = QName
substitutionGroup = QName type = QName
{any attributes with non-schema namespace . . .}> Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
</element>
属性
Schema Component: Attribute Declaration
{name}
An NCName as defined by [XML-Namespaces].
{target namespace}
Either ·absent· or a namespace name, as defined in [XML- Namespaces].
{type definition}
A simple type definition.
{scope}
Optional. Either global or a complex type definition.
{value constraint}
Optional. A pair consisting of a value and one of default, fixed.
{annotation}
Optional. An annotation.
XML Representation Summary: attribute Element Information Item
<attribute default = string fixed = string
form = (qualified | unqualified) id = ID
name = NCName ref = QName type = QName
use = (optional | prohibited | required) : optional
{any attributes with non-schema namespace . . .}> Content: (annotation?, simpleType?)
</attribute>
数据类型
语法
- 元素类型名称
<elementType name="name">
<mixed/>
</elementType>
- 邮政编码数据类型
<datatype name="zipCode">
<basetype name="string"/>
<lexicalRepresentation>
<lexical>99999</lexical>
<lexical>99999-9999</lexical>
</lexicalRepresentation>
</datatype>
- zip数据类型
<elementType name="zip">
<datatypeRef name="zipCode"/>
</elementType>
- Schema定义的Address定义
<elementType name="address">
<sequence>
<elementTypeRef name="company" minOccur="0 maxOccur="1"/>
<elementTypeRef name="name" minOccur="1" maxOccur="1"/>
<elementTypeRef name="street" minOccur="1" maxOccur="2"/>
<elementTypeRef name="city" minOccur="1" maxOccur="1"/>
<elementTypeRef name="state" minOccur="1" maxOccur="1"/>
<elementTypeRef name="zip" minOccur="1" maxOccur="1"/>
</sequence>
</elementType>
- DTD中
<address>
的声明
<!ELEMENT address (company?,name, street+, city, state, zip)>
DTD中含parameter entity(参数体)的address
<!ENTITY % address "company?, name, street+, city, state, zip">
<!ELEMENT billing.address (%address;) >
<!ELEMENT shipping.address (%address;) >
- XML Schema中含Archetype (原型)的address
<archetype name="address" model="refinable">
<sequence>
<elementTypeRef name="company" minOccur="0" maxOccur="1"/>
<elementTypeRef name="name" minOccur="1" maxOccur="1"/>
<elementTypeRef name="street" minOccur="1" maxOccur="2"/>
<elementTypeRef name="city" minOccur="1" maxOccur="1"/>
<elementTypeRef name="state" minOccur="1" maxOccur="1"/>
<elementTypeRef name="zip" minOccur="1" maxOccur="1"/>
</sequence>
</archetype>
<elementType name="billing.address">
<archetypeRef name="address"/>
</elementType>
<elementType name="shipping.address">
<archetypeRef name="address"/>
</elementType>
- 复杂类型和简单类型之间最根本的区别就是:复杂类型的内容中可以包含其他元素,也可以带有属性(Attribute),但简单类型既不能包含子元素,也不能带有任何属性。
比如:
<xsd:complexType name="CNAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
-
element存在约束:element可以通过其minOccurs和maxOccurs两个属性来约束元素实例存在的个数,这两个属性的缺省值都是1,表示默认情况下此元素在XML实例文档中必须出现一次。
-
attribute存在约束:元素属性也可以通过attribute的use属性来约束出现一次或根本不出现;use属性的取值可以是required,optional,prohibited三个值,缺省(默认)值是optional.
-
element和attribute都有一个default和fixed属性,针对element来说,只有当element实例为空时才采用此default 值,而attribute是当实例不提供此attribute时才采用此default值,因此对attribute而言,只有其use值是optional 时default值才有意义,而且对element和attribute来说fixed 和default两个属性不能同时存在,否则会出现错误。
-
有三种通过限定性约束定义的新类型:
- 通过值范围限定:
<xsd:simpleType name="myInteger"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType>
- 使用模式匹配限定:
<xsd:simpleType name="SKU"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{3}-[A-Z]{2}"/> </xsd:restriction> </xsd:simpleType>
- 使用枚举方式限定:
<xsd:simpleType name="CNCity"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="BeiJing"/> <xsd:enumeration value="NanChang"/> <xsd:enumeration value="ShangHai"/> </xsd:restriction> </xsd:simpleType>
-
原子类型(不可分割的类型,象string,integer等 系统内建的类型)、列表类型、联合类型合起来统一称为简单类型。在Schema中有NMTOKENS、IDREFS、ENTITIES三种内建的列表类型,你也 可以从已有的简单类型来创建list(列表)类型,但你 不能从已有的list类型和复杂类型来创建列表(list) 类型
-
在XML实例文档中列表类型的值是通过空格来进行分隔
的,如果声明了一个listOfMyIntType元素,其值可能是:<listOfMyInt>20003 15037 95977 95945</listOfMyInt>
举例:
schema为: <xsd:simpleType name="listOfMyIntType"> <xsd:list itemType="myInteger"/> </xsd:simpleType> xml为: <listOfMyInt>20003 15037 95977 95945</listOfMyInt>
-
有几个方面的元素可以应用于list类型来进行约束,它们是:length、minLength、maxLength和enumeration,如:
<xsd:simpleType name="USStateList"> <xsd:list itemType="USState"> </xsd:list> </xsd:simpleType> <xsd:simpleType name="SixUSStates"> <xsd:restriction base="USStateList"> <xsd:length value="6"/> </xsd:restriction> </xsd:simpleType>
-
注:针对列表类型要千万注意成员是string类型的,因为string类型中的空格和列表类型的分割符空格会造成部分混淆。
-
对元素的定义可以采用通过指定其type属性为已定义的属性的方式, 也可一采用匿名定义类型的方式,如:
- 采用类型定义:
<xsd:element name=”comment” type=”xsd:string”>
- 采用匿名定义:
<xsd:element name="quantity"> <xsd:simpleType> <xsd:restriction base="xsd:positiveInteger"> <xsd:maxExclusive value="100"/> </xsd:restriction> </xsd:simpleType> </xsd:element>
-
union(联合)类型表示在XML实例文档中的元素实例符合union类型定义的成员类型中的一种就可以了(合法),这一点和C++中的联合类型有类似的概念,如:
<xsd:simpleType name="addrUnion"> <xsd:union memberTypes="xsd:string integer"/> </xsd:simpleType>
则,类型是string ,或 integer都可以了。
-
复杂类型一般可以分为三类:第一类是包含字符内容和属性但不包含子元素;第二类是包含属性和子元素但不包含字符数据(字符数据包含在子元素 中);第三类是即包含属性和字符内容又包含子元素的;那么如何来定义这三类类型呢?针对第一类可以通过simpleContent来实现,第二类可以通过complexContent来做到,第三类只需要将complexType的属性mixed设为true 就可以了。具体的例子如下:
- 第一种类型(从一个简单类型扩展而来,增加了属性):
- 第二种类型(有一个element和两个attribute构成):
<xsd:element name="internationalPrice"> <xsd:complexType> <xsd:complexContent> <xsd:element name="Country" type="xsd:string"/> <xsd:attribute name="currency" type="xsd:string"/> <xsd:attribute name="value" type="xsd:decimal"/> </xsd:complexContent> </xsd:complexType> </xsd:element>
- 第三种类型:
<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"/> minOccurs="0"/> <xsd:element name="shipDate" type="xsd:date" </xsd:sequence> </xsd:complexType> </xsd:element>
- 第三种类型的实例可能如下:
<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>
-
根据上例的描述那么要定义一个空内容的元素,也就是说定义一个只包含属性的元素,只要在complexContent中不包含任何子元素,就可以了,如:
<xsd:element name="internationalPrice"> <xsd:complexType> <xsd:attribute name="currency" type="xsd:string"/> <xsd:attribute name="value"type="xsd:decimal"/> </xsd:complexType> </xsd:element>
-
anyType是所有Schema类型的基类型,和Java中的Object类似。因此,以下定义:
<xsd:element name="anything" type="xsd:anyType"/>
可以写成:
<xsd:element name="anything"/>
引用XSD
<?xml version="1.0"?>
<example xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLS chema-instance"
xsi:schemaLocation="http://www.example. com/example.xsd">
<…>…</…>
</example>
模式语言
- DTD
- XML Schema
- RELAX NG
- Schematron
- XDR
- XSD