![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=1738862920-zxokKbMajLB4InpU0ecUWNnAVsdWYN79-0-9aeb562f4c9ade960c8dba2d2aadb95c)
这个声明说明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=1738862920-MBNHxQje0mWXb6RtzGBljsoQZRF3aMCi-0-9cf92a8cbda0e55369984741170e5293)
注意:我们用前缀xsd:来表示XSL Schema定义的命名空间。一些作者代之以xs:。
可以定义自己的简单类型。例如,下面是一个枚举类型:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-2-i.jpg?sign=1738862920-SIcKAjo3xm1lLCF912076ra6pwHwBFNl-0-55eabdfe6cd0fdaa5f4bb602748ad978)
当定义元素时,要指定它的类型:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-3-i.jpg?sign=1738862920-XdKDQG9qO05ixaV9KG3Qd21WA6Onbqff-0-d48870c8af1f2f870d931450947de40f)
类型约束了元素的内容。例如,下面的元素将被验证为具有正确格式:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-4-i.jpg?sign=1738862920-rxHF0vKZzez4IfYcr87jmO1fUmvv2M2T-0-2776efba41169b957d6fc3952576fdf4)
但是,下面的元素会被解析器拒绝:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-5-i.jpg?sign=1738862920-nbdKYXPQbpKXRExLvLPSenvLJmnl6F0b-0-6a67f979c24f3483e65715fbd86db5b4)
FontType是name、size和style元素的序列。在这个类型定义中,我们使用了ref属性来引用在Schema中位于别处的定义。也可以嵌套定义,像这样:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/140-6-i.jpg?sign=1738862920-z9c4KnIMpqpQAfjteBGJpRDDgXlNsvi7-0-3cf7c748937712da98dc5a872be59148)
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-i.jpg?sign=1738862920-tsJNSosDVZKFCTv5aIVabrdfjHqhUSCd-0-77e2ec066d7fce91bb22ef05913dbb1a)
请注意style元素的匿名类型定义。
xsd:sequence结构和DTD中的连接符号等价,而xsd:choice结构和|操作符等价,例如:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-2-i.jpg?sign=1738862920-6uzmmeYo64u0vrSt2QwNxHGkETrAHuDA-0-3c46e23e34b6be18690661777a496661)
这和DTD中的类型email|phone类型是等价的。
如果要允许重复元素,可以使用minoccurs和maxoccurs属性,例如,与DTD类型item*等价的形式如下:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-3-i.jpg?sign=1738862920-sBDpj6HS36U09SoGahs3sR6b3OqFU5Vp-0-6cf0eb81a00d7bf8fef3c56a598199dd)
如果要指定属性,可以把xsd:attribute元素添加到complexType定义中去:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-4-i.jpg?sign=1738862920-f1KmAy28VsF0YrTPUeUMSC5lKY8x2z7o-0-296dcd91fd9811c91334bb0866da7cc1)
这与下面的DTD语句等价:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-5-i.jpg?sign=1738862920-USl4oEUnzEgdvPxwSN3gQwNz0q5uoKkj-0-a9a607155313977fa4d5d1b4f2fd45e4)
可以把Schema的元素和类型定义封装在xsd:schema元素中:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-6-i.jpg?sign=1738862920-6UOUR19zHYvGcRg0ZpaRVUtav5jDOVHf-0-2c303f17531bf888c885287ecd801d25)
解析带有Schema的XML文件和解析带有DTD的文件相似,但有3点差别:
1)必须打开对命名空间的支持,即使在XML文件里你可能不会用到它。
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-7-i.jpg?sign=1738862920-2ipKh8Uj50ciSM5PoaFcaIhy4Sa2NsLJ-0-4d7a604003d3de268c0a173af9897362)
2)必须通过如下的“魔咒”来准备好处理Schema的工厂。
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/141-8-i.jpg?sign=1738862920-1RTIbROnRpLBAsl9w2J2TLfBpNW0uz5f-0-3caf2c3c34caed1fad6e66106995cf0f)
3)解析器不会丢弃元素中的空白字符,这确实很令人恼火,关于这是否是一个bug,人们看法不一。有一种变通方法,请参看程序清单3-4中的代码。