第六章 命名空间详解
6.1 使用命名空间
在XML文档中通过xmlns(XML Namespace)或者xmlns:prefix来使用命名空间,xmlns或xmlns:prefix是一个特殊的保留属性
命名空间只是XML元素和XML属性所在的范围,因此,从语法要求的角度来讲,命名空间可以是一个任意的字符,但实际使用中往往是一个绝对的URL地址
根据实际的开发经验,为XML元素或属性指定命名空间时以本公司/组织的域名+项目名+模块名作为命名空间比较合适
由于XML命名空间很长,还带有英文冒号、斜线等特殊字符,在XML文档中使用命名空间时往往需要指定一个别名 xmlns[:prefix]="命名空间字符串"
6.2 Schema的命名空间支持
6.2.1 在Schema中使用命名空间
在定义一份Schema时可以在根元素中指定targetNamespace属性,表明该Schema定义的元素、属性和类型等Schema组件放在哪个命名空间下,以后不管是在XML文档还是在Schema中,使用这些Schema组件都必须使用命名空间
namespace_Schema1.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.crazyit.org/schema" targetNamespace="http://www.crazyit.org/schema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 定义了一个book-list元素 --> <xs:element name="book-list"> <xs:complexType> <xs:sequence> <!-- 使用当前Schema里的book元素,因为当前Schema位于 http://www.crazyit.org/schema命名空间下 ,而且该命名空间 没有指定限定短名,因此使用book元素时必须用如下所示的形式 --> <xs:element ref="book" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- 定义一个item_Type复杂类型 --> <xs:complexType name="item_Type"> <xs:sequence> <xs:element name="book-name" type="xs:token"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> <!-- 使用http://www.crazyit.org/schema命名空间下的item_Type类型时 无需添加限定前缀 --> <xs:element name="book" type="item_Type"/> </xs:schema>
上面的Schema中指定了targetNamespace=http://www.crazyit.org/schema,这表明该Schema定义的所有组件都位于该命名空间下,不论在哪里使用这些组件都必须使用其命名空间前缀
上面的Schema在根元素中指定了xmlns="http://www.crazyit.org/schema",这表明该命名空间的前缀为空字符串(即无须命名空间前缀),因此上面的Schema中使用<book.../>元素和ite_Type类型时没有加任何前缀
namespace_Schema2.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:crazyit="http://www.crazyit.org/schema" targetNamespace="http://www.crazyit.org/schema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 定义了一个book-list元素 --> <xs:element name="book-list"> <xs:complexType> <xs:sequence> <!-- 使用当前Schema里的book元素,因为当前Schema位于 http://www.crazyit.org/schema命名空间下 ,而且该命名空间 对应的限定短名是crazyit,因此使用book元素时必须用如下所示的形式 --> <xs:element ref="crazyit:book" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- 定义一个item_Type复杂类型 --> <xs:complexType name="item_Type"> <xs:sequence> <xs:element name="book-name" type="xs:token"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> <!-- 使用http://www.crazyit.org/schema命名空间下的item_Type类型时 应添加该命名空间对应的限定前缀 --> <xs:element name="book" type="crazyit:item_Type"/> </xs:schema>
上丽的Schema 中的targetNamespace 属性依然是http://www.crazyit.orglschema. 这表明该Schema所包含的Schema 组件依然处于该命名空间之下, 但其根元素中指定了xmlns:crazyil=“hltp://www.crazyit.org/schema" .这意味着http://www.crazyi l.org/schema 命名空间对应的限定短名为crazyit . 因此该Schema 中使用其<book…/>元索时必须用<crazyit:book.../>的形式一一其中的crazyit 就是http://www.crazyit.org/schema 对应的限定短名,它是可以随意指定的
此外,并不是只能在XML 根元素里指定xmlns: prefix 属性. XML (Schema 也是XML 的一种)允许为任何元素指定xmlns:prefix 属性. 在为某个元索指定了xm1ns: prefix 属性后,该元素及其所有子元素都可使用该prefix 作为命名空间的限定短名
namespace_Schema3.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:crazyit="http://www.crazyit.org/schema" targetNamespace="http://www.crazyit.org/schema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 定义了一个book-list元素 --> <xs:element name="book-list"> <xs:complexType> <xs:sequence xmlns:java="http://www.crazyit.org/schema"> <!-- 使用当前Schema里的book元素,因为当前Schema位于 http://www.crazyit.org/schema命名空间下 ,而且该命名空间 对应的限定短名是java:,因此使用book元素时可用如下所示的形式 --> <xs:element ref="java:book" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- 定义一个item_Type复杂类型 --> <xs:complexType name="item_Type"> <xs:sequence> <xs:element name="book-name" type="xs:token"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> <!-- 使用http://www.crazyit.org/schema命名空间下的item_Type类型时 应添加该命名空间对应的限定前缀 --> <xs:element name="book" type="crazyit:item_Type"/> </xs:schema>
6.2.2 局部元素和局部属性的强制限定
前面定义Schema时总是为根元素指定如下两个属性:
- elementFormDefault=”qualified“
- attributeFormDefault="unqualified"
这两个属性也是与命名空间相关的,其中elementFormDefault 用于指定XML 文档中使用局部元素时是否必须使用限定短名作为前缀,如果该属性值为qualified. 则表明必须使用限定短名作为前缀,否则可以省略限定短名
element_unqualified.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.crazyit.org/schema" xmlns:crazy="http://www.crazyit.org/schema" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <!-- 定义一个book_Type复杂类型 --> <xs:complexType name="book_Type"> <!-- 定义可包含2个有序的子元素 注意下面两个子元素是局部子元素, 由于前面指定了elementFormDefault="unqualified",因此在XML文档中使用这两个元素时无需使用限定短名作为前缀 --> <xs:sequence> <xs:element name="book-name" type="xs:token"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> <xs:element name="book-list"> <xs:complexType> <!-- 定义可以包含无限多个有序的book元素 --> <xs:sequence> <!-- book也是局部元素,因此也可不使用限定短名作为前缀 --> <xs:element name="book" type="crazy:book_Type" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
上面的Schema 中定义的〈book-name. . ./>和<price.../>两个元素是局部元素,而且该Schema指定了elementFormDefault="unqualified",因此在XML文档中时使用限定短名作为前缀
element_unqualified.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 由于指定了xmlns:crazy="http://www.crazyit.org/schema", 即http://www.crazyit.org/schema命名空间对应的限定短名为crazy 根元素必须使用限定短名作为前缀 --> <crazy:book-list xmlns:crazy="http://www.crazyit.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.crazyit.org/schema element_unqualified.xsd"> <book> <book-name>疯狂Ajax讲义</book-name> <price>69.00</price> </book> </crazy:book-list>
从上面的代码来看,XML 文档中使用〈book.../>、<book-name.../>和<price.../>等局部元素时无须添加限定短名
必须指出的是:elementFormDefault="unqualified"仅对局部元素有效,对于Schema中的全局元素而言,不管该属性如何设置,在XML中使用时总是必须使用限定短名作为前缀
element_unqualified2.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.crazyit.org/schema" xmlns:crazy="http://www.crazyit.org/schema" elementFormDefault="unqualified" attributeFormDefault="unqualified"> <!-- 定义一个book_Type复杂类型 --> <xs:complexType name="book_Type"> <!-- 定义可包含2个有序的子元素 注意下面两个子元素是局部子元素, 由于前面指定了elementFormDefault="unqualified",因此在XML文档中使用这两个元素时无需使用限定短名作为前缀 --> <xs:sequence> <xs:element name="book-name" type="xs:token"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> <!-- 把book元素定义成全局元素 --> <xs:element name="book" type="crazy:book_Type"/> <xs:element name="book-list"> <xs:complexType> <!-- 定义可以包含无限多个有序的book元素 --> <xs:sequence> <!-- book也是全局元素,因此在XML中必须限定短名作为前缀 --> <xs:element ref="crazy:book" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
上面的Schema 中<book.../> 元素是一个全局元索,因此在XML 文档中使用该元素时必须使用限定短名作为前缀
element_unqualified2.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 由于指定了xmlns:crazy="http://www.crazyit.org/schema", 即http://www.crazyit.org/schema命名空间对应的限定短名为crazy 根元素必须使用限定短名作为前缀 --> <crazy:book-list xmlns:crazy="http://www.crazyit.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.crazyit.org/schema element_unqualified2.xsd"> <!-- 由于Schema定义book元素时是全局元素,因此使用时必须指定限定短名 --> <crazy:book> <book-name>疯狂Ajax讲义</book-name> <price>69.00</price> </crazy:book> </crazy:book-list>
在Schema 的根元素里指定了elementFonnDefault="unqualified"之后,在XML文档中使用该Schema 定义的局部元素时不能使用限定短名作为前缀,这样可以使该XML文档更简洁,但却会降低其可读性。 因此通常推荐将elementFormDefault属性值设置为qualified
类似地,如果指定了attributeFormDefault="qualified",则要求XML文档中使用局部属性时必须使用限定短名作为前缀。attributeFormDefault="qualified"的设置仅对局部属性起作用, 不管该属性如何设置,在XML 文档中使用全局属性时总是需要添加限定短名作为前缀的
attribute_unqualified.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.crazyit.org/schema" xmlns:crazy="http://www.crazyit.org/schema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 定义一个book_Type复杂类型 --> <xs:complexType name="book_Type"> <!-- 定义了2个局部属性,由于指定了attributeFormDefault="unqualified" 因此使用这两个属性时无需使用限定短名作为前缀 --> <xs:attribute name="book-name" type="xs:token"/> <xs:attribute name="price" type="xs:decimal"/> </xs:complexType> <xs:element name="book-list"> <xs:complexType> <!-- 定义可以包含无限多个有序的book元素 --> <xs:sequence> <xs:element name="book" type="crazy:book_Type" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute ref="crazy:desc" use="required"/> </xs:complexType> </xs:element> <!-- 定义一个全局属性,因此使用该属性时总需要使用限定短名作为前缀 --> <xs:attribute name="desc" type="xs:token"/> </xs:schema>
attribute_unqualified.xml
<?xml version="1.0" encoding="UTF-8"?> <crazy:book-list crazy:desc="测试属性" xmlns:crazy="http://www.crazyit.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.crazyit.org/schema attribute_unqualified.xsd"> <crazy:book book-name="疯狂Java讲义" price="99.00"/> </crazy:book-list>
如果在Schema中指定了attributeFormDefault="qualified" 。则在XML 文档中使用局部属性时也必须添加限定短名作为前缀
attribute_unqualified2.xsd
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.crazyit.org/schema" xmlns:crazy="http://www.crazyit.org/schema" elementFormDefault="qualified" attributeFormDefault="qualified"> <!-- 定义一个book_Type复杂类型 --> <xs:complexType name="book_Type"> <!-- 定义了2个局部属性,由于指定了attributeFormDefault="qualified" 因此使用这两个属性时必须使用限定短名作为前缀 --> <xs:attribute name="book-name" type="xs:token"/> <xs:attribute name="price" type="xs:decimal"/> </xs:complexType> <xs:element name="book-list"> <xs:complexType> <!-- 定义可以包含无限多个有序的book元素 --> <xs:sequence> <xs:element name="book" type="crazy:book_Type" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute ref="crazy:desc" use="required"/> </xs:complexType> </xs:element> <!-- 定义一个全局属性,因此使用该属性时总需要使用限定短名作为前缀 --> <xs:attribute name="desc" type="xs:token"/> </xs:schema>
attribute_unqualified2.xml
<?xml version="1.0" encoding="UTF-8"?> <crazy:book-list crazy:desc="测试属性" xmlns:crazy="http://www.crazyit.org/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.crazyit.org/schema attribute_unqualified2.xsd"> <crazy:book crazy:book-name="疯狂Java讲义" crazy:price="99.00" /> </crazy:book-list>
需要指出的是,由于属性总是属于某个元素的.。XML 文档用户很容易确定该属性所处的命名空间一一总是处于其所属元素所处的命名空间内,因此使用局部属性时通常无须添加限定短名作为前缀,所以Schema中通常会指定attributeFormDefault="unqualified",表明在XML文档中使用局部属性时无须添加限定短名作为前缀.
原文链接:https://www.f2er.com/xml/299687.html