![Java核心技术·卷Ⅱ:高级特性(原书第10版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/937/34339937/b_34339937.jpg)
3.3.2 XML Schema
因为XML Schema比起DTD语法要复杂许多,所以我们只涉及其基本知识。更多信息请参考http://www.w3.org/TR/xmlschema-0上的指南。
如果要在文档中引用Schema文件,需要在根元素中添加属性,例如:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/139-i.jpg?sign=1738864610-ErkIXVPk3nbfMuojR6X0xaKSRjvNUqWt-0-c5922547188ca739e9cba8e66fdfdfb5)
这个声明说明Schema文件config.xsd会被用来验证该文档。如果使用命名空间,语法就更加复杂了。详情请参见XML Schema指南(前缀xsi是一个命名空间别名(namespace alias),请查看第3.5节以了解更多信息)。
Schema为每个元素都定义了类型。类型可以是简单类型,即有格式限制的字符串,或者是复杂类型。一些简单类型已经被内建到了XML Schema内,包括:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-i.jpg?sign=1738864610-QCKPocVGo1XCGmTUVwKwUDOTn6NAIblg-0-2b543018476b30715b4f05155be84cf7)
注意:我们用前缀xsd:来表示XSL Schema定义的命名空间。一些作者代之以xs:。
可以定义自己的简单类型。例如,下面是一个枚举类型:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-2-i.jpg?sign=1738864610-uM1W1MBqvFVp6ADGVkH6c6IWAwgSl7oo-0-ea74b2829bc15962309a4883cb8ab346)
当定义元素时,要指定它的类型:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-3-i.jpg?sign=1738864610-Sgdg8HGDBsTWZggJxLUCLTqxoWeLxedM-0-29714f72a99fcd46b5c07429645c1fc9)
类型约束了元素的内容。例如,下面的元素将被验证为具有正确格式:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-4-i.jpg?sign=1738864610-9yrrt7fMM7HJVnkaTTclqgwaJZ098Ogj-0-288f0f53de0dd9a45a83c3f021586836)
但是,下面的元素会被解析器拒绝:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-5-i.jpg?sign=1738864610-iIQCQGr1LedWz32AYID658CvczWbmFZM-0-1a075eb8b875900ff667b404d70529ca)
FontType是name、size和style元素的序列。在这个类型定义中,我们使用了ref属性来引用在Schema中位于别处的定义。也可以嵌套定义,像这样:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-6-i.jpg?sign=1738864610-5oB0vxnbb3vtg908tdQxuNmCeqARRZwQ-0-7e31fffcf7325f66e13188c90b581b8f)
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-i.jpg?sign=1738864610-I85xCPWfOJqhEfckaFofZNQSpY3LVFzg-0-30e2214c4afb8d81078558431c44d639)
请注意style元素的匿名类型定义。
xsd:sequence结构和DTD中的连接符号等价,而xsd:choice结构和|操作符等价,例如:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-2-i.jpg?sign=1738864610-aFHKRTgtiVyoCzNSItGCmLHsmhCURK4l-0-f75e882242c2931aaa60e3b72ae5390b)
这和DTD中的类型email|phone类型是等价的。
如果要允许重复元素,可以使用minoccurs和maxoccurs属性,例如,与DTD类型item*等价的形式如下:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-3-i.jpg?sign=1738864610-rX0KUxndx0Kcq4anZ51yh67YwCrvBZTZ-0-168bce67f6a9c79ad76187ea6097c99b)
如果要指定属性,可以把xsd:attribute元素添加到complexType定义中去:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-4-i.jpg?sign=1738864610-Ifn2yaM8Sr2KBqlhg1jZ3exIxqEDhSgq-0-263f09dbcd781fc94d9da419703d8648)
这与下面的DTD语句等价:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-5-i.jpg?sign=1738864610-LvSpZH9K6x0ksfdBb74fibxfLlVwrEsk-0-b3d0b320bb351e42278728703ab42ca0)
可以把Schema的元素和类型定义封装在xsd:schema元素中:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-6-i.jpg?sign=1738864610-TdWIT4Dd5WUn0FjFpaMX3av2tESqSDoL-0-9fee1b51bddc66b1eca04fc83b44f042)
解析带有Schema的XML文件和解析带有DTD的文件相似,但有3点差别:
1)必须打开对命名空间的支持,即使在XML文件里你可能不会用到它。
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-7-i.jpg?sign=1738864610-mfn3jRri9SJmpuIqLqFfh3DKzlfpVhlE-0-cdbb9bfb285d8db57306551a572f18f2)
2)必须通过如下的“魔咒”来准备好处理Schema的工厂。
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-8-i.jpg?sign=1738864610-1MsqZGJqvOM8uOpTZds3HIWCV5Fgk2Ja-0-44d8882d0a6efe500ec07b8f4f0b3050)
3)解析器不会丢弃元素中的空白字符,这确实很令人恼火,关于这是否是一个bug,人们看法不一。有一种变通方法,请参看程序清单3-4中的代码。