XMLSchema 模式与命名空间

XMLSchema 模式与命名空间

模式与名称空间

DTD的问题就在于和名称空间不相关,当你为一个XML文档使用了名称空间后,文档的DTD就需要重写。XML Schema对名称空间提供了很好的支持。在编写模式文档时,你可以指定该模式文档是为哪一个名称空间声明和定义组件,这个名称空间称为目标名称空间

4.5.6.1  目标名称空间

目标名称空间使用xs:schema元素的targetNamespace属性来指定,如例4-16所示。

例4-16  book3.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.sunxin.org/book"  ①
xmlns:book="http://www.sunxin.org/book">   ②
<xs:element name="book" type="book:bookType"/>  ③

<xs:complexType name="bookType">     ④
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>

① 我们在xs:schema元素上使用targetNamespace属性指定目标名称空间为:http://www.sunxin.org/book,即指明了在该模式文档中声明的元素、定义的类型都属于http://www.sunxin.org/book名称空间。

② 声明名称空间http://www.sunxin.org/book,并为该名称空间绑定前缀book,使用该前缀来引用http://www.sunxin.org/book名称空间中的类型。

③ 由于指定了目标名称空间,文档中定义的类型都属于目标名称空间,因此在引用类型时,需要加上book前缀。

④ 在指定类型名时,不需要加上任何前缀,当使用了targetNamespace属性后,在模式文档中定义的任何类型都属于目标名称空间。

在模式文档中,我们很容易就能区分出不同名称空间中的元素和类型,带有xs前缀的元素和类型属于http://www.w3.org/2001/XMLSchema名称空间,而其他的元素和类型则属于目标名称空间。需要注意的是,只有模式文档中的全局元素和全局属性才属于目标名称空间,在本例中,声明的全局元素name属于目标名称空间,而局部元素title和author则不属于目标名称空间。

为了简化模式文档对目标名称空间中的元素和类型的引用,我们可以利用默认名称空间来简化引用,例4-16如果使用了默认名称空间,可以修改为如例4-17所示。

例4-17  使用了默认名称空间的book4.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.sunxin.org/book"
xmlns="http://www.sunxin.org/book">
<xs:element name="book" type="bookType"/>

<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>

我们在xs:schema元素上声明了默认名称空间http://www.sunxin.org/book,因此在声明book元素时,引用bookType类型就无须再添加前缀了。

符合上述模式文档的XML实例文档如例4-18所示。

例4-18  book.xml

<?xml version="1.0" encoding="GB2312"?>
<book:book xmlns:book="http://www.sunxin.org/book" isbn="978-7-121-06812-6">  
<title>《Struts 2深入详解》</title>
<author>孙鑫</author>
</book:book>

在例4-17的模式文档中,在bookType类型定义中声明的元素title和author是局部元素,没有被目标名称空间所限定,因此在实例文档中,对title和author元素不要添加book前缀。

局部元素和属性的限定

在例4-17中,局部元素title和author没有被目标名称空间所限定,如果要限定局部元素和属性,可以通过xs:schema元素的elementFormDefault和attibuteFormDefault属性来设置。

为了指定模式文档中局部声明的元素必须被限定,可以将xs:schema元素的elementFormDefault属性的值设为"qualified"。

将例4-17中的xs:schema元素修改为如例4-19所示。

例4-19  book5.xsd

 

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.sunxin.org/book"
xmlns="http://www.sunxin.org/book"
elementFormDefault="qualified">
<xs:element name="book" type="bookType"/>

<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>

elementFormDefault属性的默认值是unqualified,即对局部声明的元素不加限定。

我们修改了模式文档,相应的就要修改实例文档,如例4-20所示。

例4-20  book2.xml

 

<?xml version="1.0" encoding="GB2312"?>
<book:book xmlns:book="http://www.sunxin.org/book" isbn="978-7-121-06812-6">
<book:title>《Struts 2深入详解》</book:title>
<book:author>孙鑫</book:author>
</book:book>

在例4-20的实例文档中,所有的元素都属于同一个名称空间,因此我们可以声明一个默认的名称空间,来省略前缀的使用,如例4-21所示。

例4-21  book3.xml

 

<?xml version="1.0" encoding="GB2312"?>
<book xmlns="http://www.sunxin.org/book" isbn="978-7-121-06812-6">
<title>《Struts 2深入详解》</title>
<author>孙鑫</author>
</book>

属性的限定和元素的限定是类似的。如果属性被声明为全局属性或者xs:schema元素的attibuteFormDefault属性被设置成"qualified"的话,那么属性就必须被限定,在实例文档中将以带名称空间前缀的方式出现。实际上,需要限定的属性必须明确的加上名称空间前缀,因为XML名称空间推荐标准中并没有给出关于属性的默认名称空间的机制,一个没有前缀的属性将不在任何的名称空间中。属性是附属于元素的,对属性添加名称空间不是很有必要,因此在多数应用中都没有给属性添加限定。

使用了attibuteFormDefault属性的模式文档,如例4-22所示。

例4-22  book6.xsd

 

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns="http://www.sunxin.org/book" 
targetNamespace="http://www.sunxin.org/book" 
elementFormDefault="qualified" 
attributeFormDefault="qualified">
 <xs:element name="book" type="bookType"/>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>

attributeFormDefault属性的默认值是unqualified,即对局部声明的属性不加限定。

一个符合模式(例4-22)的实例文档如例4-23所示。

例4-23  book4.xml

 

<?xml version="1.0" encoding="GB2312"?>
<book:book xmlns:book="http://www.sunxin.org/book" book:isbn="978-7-121-06812-6">
<book:title>《Struts 2深入详解》</book:title>
<book:author>孙鑫</book:author>
</book:book>

除了使用xs:schema元素的elementFormDefault和attibuteFormDefault属性来限定局部元素和局部属性外,我们还可以在xs:element和xs:attribute元素上分别使用form属性来限定局部元素和局部属性。我们看例4-24。

例4-24  book7.xsd

 

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns="http://www.sunxin.org/book" 
targetNamespace="http://www.sunxin.org/book">
<xs:element name="book" type="bookType"/>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string" form="qualified"/>
<xs:element name="author" type="xs:string" form="qualified"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token" form="qualified"/>
</xs:complexType>
</xs:schema>

例4-24所示的模式文档和例4-22所示的模式文档的效果是一样的。 

注意的是,在xs:schema元素上使用elementFormDefault和attibuteFormDefault属性,影响的是整个模式文档中的局部元素和局部属性,而在xs:element和xs:attribute元素上使用form属性,影响的是当前的局部元素和局部属性。

未声明的目标名称空间

对于很多不使用名称空间的XML文档,你需要使用没有声明目标名称空间的模式文档。我们看例4-25。

例4-25  book8.xsd

 

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book" type="bookType"/>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>

在这个模式文档中我们没有声明目标名称空间,因此定义的bookType类型和声明的book元素都是没有名称空间限定的。在引用类型或元素时,不需要添加任何的名称空间前缀。在本例中,声明book元素时,type属性直接引用了bookType类型。与之相对的是,例4-25的模式文档中使用的所有XML Schema元素和类型都是通过与XML Schema名称空间相关联的名称空间前缀"xs"来明确进行限定的。

一个符合模式(例4-25)的实例文档如例4-26所示。

例4-26  book5.xml

 

<?xml version="1.0" encoding="GB2312"?>
<book isbn="978-7-121-06812-6">
<title>《Struts 2深入详解》</title>
<author>孙鑫</author>
</book>

注意的是,在没有声明目标名称空间的模式文档中,强烈建议对所有的XML Schema元素和类型使用一个和XML Schema名称空间相关联的名称空间前缀(如xs或xsd)来明确实施限定。如果你对XML Schema的元素和类型使用了默认名称空间,那么对XML Schema类型的引用也许不能和对用户自定义类型的引用相区分,从而导致模式文档出现错误。例4-27错误的使用了默认名称空间,使得对自定义类型的引用和对XML Schema类型的引用不能区分。

例4-27  book9.xsd

 

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="book" type="bookType"/>
<complexType name="bookType">
<sequence>
<element name="title" type="string"/>
<element name="author" type="string"/>
</sequence>
<attribute name="isbn" type="token"/>
</complexType>
</schema>

在XMLSpy中验证这个模式文档时,将提示如下的错误信息:

 

'bookType' must refer to an existing simple or complex type.

这是因为模式验证器认为对bookType类型的引用(没有前缀的引用),引用的是默认名称空间(即http://www.w3.org/2001/XMLSchema名称空间)中的类型,而XML Schema名称空间中并没有bookType这种类型,因此就报出了错误。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值