xml schema中的namespace分析

我们知道,namespace在xml中占有重要的地位,其是xml的核心标准之一。所以,xml schema、xml query等后来的标准都对namespace有较好的支持。namespace很琐碎,是广大xml初学者的绊脚石。下面讲讲xml schema中的namespace,让大家消除点恐惧。

xml schema对namespace的支持体现在targetNamespace上,每个xml schema文档有一个顶层的schema元素,其targetNamespace就是全局成分所在的名字空间(全局成分指的是元素xsd:schema的直接子节点,包括元素声明、属性声明、复杂/简单类型定义、组定义、属性组定义).

属性elementFormDefault的默认值是unqualified,也就是规定了只有全局成分才被定义在目标名称空间中。将elementFormDefault的值赋为qualified,使得目标名称空间包含非全局的元素定义。同样,使属性attributeFormDefault的值赋为qualified,可使得目标名称空间包含非全局属性定义。如以下文档client.xsd,所有的元素均在namespace “www.shitou.com”中。至于声明xmlns=“www.shitou.com”,为的是ref的时候不用写namespace前缀了。否则,诸如

<xs:element ref="街道"/>
    <xs:element ref="城市"/>
    <xs:element ref="省份"/> 等语句就会出现问题了,因为No namespace的元素“街道”没有定义,client.xsd定义的只是“
www.shitou.com:街道”。

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="www.shitou.com" targetNamespace="www.shitou.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
    
<xs:element name="城市" type="xs:string"/>
    
<xs:element name="街道" type="xs:string"/>
    
<xs:element name="省份" type="xs:string"/>
    
<xs:element name="地址">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="街道"/>
                
<xs:element ref="城市"/>
                
<xs:element ref="省份"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="EMAIL" type="xs:string"/>
    
<xs:element name="ID" type="xs:string"/>
    
<xs:element name="公司" type="xs:string"/>
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="电话" type="xs:string"/>
    
<xs:element name="直接上司" type="xs:anyType"/>
    
<xs:element name="联系人">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="姓名"/>
                
<xs:element ref="ID"/>
                
<xs:element ref="公司"/>
                
<xs:element ref="EMAIL"/>
                
<xs:element ref="电话"/>
                
<xs:element ref="地址"/>
                
<xs:element ref="直接上司"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="联系人列表">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="联系人" maxOccurs="unbounded"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

当然,上面的xmlns=“www.shitou.com”的语法并不受推崇,容易造成混乱,所以下面的manager.xsd中变了以下,取消了xmlns=“www.manager.com”,取而代之的是xmlns:经理=“www.manager.com”,相应的,其中ref的地方都要加上“经理”前缀,如

<xs:element ref="经理:姓名"/>
  <xs:element ref="经理:电话"/> 这样虽然麻烦点,但是不至于造成混乱。

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:经理="www.manager.com" targetNamespace="www.manager.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
    
<xs:element name="企业经理">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:姓名"/>
                
<xs:element ref="经理:电话"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="手机" type="xs:string"/>
    
<xs:element name="秘书电话" type="xs:string"/>
    
<xs:element name="电话">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:秘书电话"/>
                
<xs:element ref="经理:手机"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

 因为一个xsd只有一个tagetNamespace属性,言下之意,也就是这个文档中定义的所有元素都属于一个namespace,这与我们的xml文件经常出现多个namespace的情况不符。于是,有必存在一种手段,将多个xsd中定义的namespace融合在一个xml文档中。

下面这个例子employee.xml融合了上面的client.xsd和manager.xsd,注意,其中声明的namespace必须和xsd中声明的targetNamespace相符,如联系人对应的www.shitou.com,企业经理对应的www.manager.com,此外,还要在xsi:schemaLocation中说明schema所在的位置,其格式是“namespace1  xsd文件路径1 namespace2 xsd文件路径2...”,这样,我们就可以在xml文档中使用我们定义的前缀了。

<?xml version="1.0" encoding="UTF-8"?>
<联系人:联系人列表 xmlns:联系人="www.shitou.com" xmlns:企业经理="www.manager.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="www.shitou.com
client.xsd www.manager.com manager.xsd"
>

    
<联系人:联系人>
        
<联系人:姓名>张三丰</联系人:姓名>
        
<联系人:ID>001</联系人:ID>
        
<联系人:公司>huawei</联系人:公司>
        
<联系人:EMAIL>zhang@huawei.com</联系人:EMAIL>
        
<联系人:电话>(0755)21530000</联系人:电话>
        
<联系人:地址>
            
<联系人:街道>高新南十一道</联系人:街道>
            
<联系人:城市>深圳市</联系人:城市>
            
<联系人:省份>广东</联系人:省份>
        
</联系人:地址>
        
<联系人:直接上司>
            
<企业经理:姓名>大刀王五</企业经理:姓名>
            
<企业经理:电话>
                
<企业经理:秘书电话>0755-21500000</企业经理:秘书电话>
                
<企业经理:手机>13800008888</企业经理:手机>
            
</企业经理:电话>
        
</联系人:直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

本例在http://bbs.w3china.org/dispbbs.asp?BoardID=23&replyID=40537&id=15255&star=1&skin=0的例子基础上修改而成,经过xml spy2006验证。

下面考虑elementFormDefault属性值unqualified和qualified的区别:

将client.xsd修改成如下所示:

 

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="www.shitou.com" targetNamespace="www.shitou.com" elementFormDefault="unqualified" attributeFormDefault="unqualified">
    
<xs:element name="城市" type="xs:string"/>
    
<xs:element name="街道" type="xs:string"/>
    
<xs:element name="省份" type="xs:string"/>
    
<xs:element name="地址">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="街道"/>
                
<xs:element ref="城市"/>
                
<xs:element ref="省份"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>     

    
<xs:element name="联系人">

        
<xs:complexType>
            
<xs:sequence>
                
<xs:element name="姓名" type="xs:string"/>
                
<xs:element name="ID" type="xs:string"/>
                
<xs:element name="公司" type="xs:string"/>
                
<xs:element name="EMAIL" type="xs:string"/>
                
<xs:element name="电话" type="xs:string"/>
                
<xs:element ref="地址" />
                
<xs:element name="直接上司" type="xs:anyType"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
    
<xs:element name="联系人列表">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="联系人" maxOccurs="unbounded"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

这个时候,“姓名、ID、公司、EMAIL、电话、直接上司”因为不再是全局成分,将elementFromDefault值设置为unqualified时,这些子元素不再属于targetNamespace,而不属于任何 namespace,所以employee.xml应修改为如下所示: 我们注意到,“姓名、ID、公司、EMAIL、电话、直接上司”前面都没有加前缀“联系人”。

<?xml version="1.0" encoding="UTF-8"?>
<联系人:联系人列表 xmlns:联系人="www.shitou.com" xmlns:企业经理="www.manager.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="www.shitou.com
client.xsd www.manager.com manager.xsd"
>

    
<联系人:联系人>
        
<姓名>张三丰</姓名>
        
<ID>001</ID>
        
<公司>huawei</公司>
        
<EMAIL>zhang@huawei.com</EMAIL>
        
<电话>(0755)21530000</电话>
        
<联系人:地址>
            
<联系人:街道>高新南十一道</联系人:街道>
            
<联系人:城市>深圳市</联系人:城市>
            
<联系人:省份>广东</联系人:省份>
        
</联系人:地址>
        
<直接上司>
            
<企业经理:企业经理>             
                
<企业经理:姓名>大刀王五</企业经理:姓名>

                
<企业经理:电话>
                    
<企业经理:秘书电话>0755-21500000</企业经理:秘书电话>
                    
<企业经理:手机>13800008888</企业经理:手机>
                
</企业经理:电话>
            
</企业经理:企业经理>
        
</直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

考虑了元素的命名空间,下面我们考虑属性的命名空间。其attributeFromDefault属性与elementFromDefault属性的用法相同。

我们将manager.xsd修改如下,添加一个属性“性别”,将attributeFormDefault 设置为"qualified",这样,“性别”属性属于命名空间targetNameSpace中。

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:经理="www.manager.com" targetNamespace="www.manager.com" elementFormDefault="unqualified" attributeFormDefault="qualified">
    
<xs:element name="企业经理">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:姓名"/>
                
<xs:element ref="经理:电话"/>
            
</xs:sequence>
            
<xs:attribute name="性别">
                
<xs:simpleType>
                    
<xs:restriction base="xs:string">
                        
<xs:enumeration value="男"/>
                        
<xs:enumeration value="女"/>
                        
<xs:enumeration value="不男不女"/>
                    
</xs:restriction>
                
</xs:simpleType>
            
</xs:attribute>  
        
</xs:complexType>

    
</xs:element>
    
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="手机" type="xs:string"/>
    
<xs:element name="秘书电话" type="xs:string"/>
    
<xs:element name="电话">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:秘书电话"/>
                
<xs:element ref="经理:手机"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

对应的employee.xml修改为如下,可以通过验证。

 

<?xml version="1.0" encoding="UTF-8"?>
<联系人:联系人列表 xmlns:联系人="www.shitou.com" xmlns:企业经理="www.manager.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="www.shitou.com
client.xsd www.manager.com manager.xsd"
>

    
<联系人:联系人>
        
<姓名>张三丰</姓名>
        
<ID>001</ID>
        
<公司>huawei</公司>
        
<EMAIL>zhang@huawei.com</EMAIL>
        
<电话>(0755)21530000</电话>
        
<联系人:地址>
            
<联系人:街道>高新南十一道</联系人:街道>
            
<联系人:城市>深圳市</联系人:城市>
            
<联系人:省份>广东</联系人:省份>
        
</联系人:地址>
        
<直接上司>
            
<企业经理:企业经理 企业经理:性别="男">             
                
<企业经理:姓名>大刀王五</企业经理:姓名>

                
<企业经理:电话>
                    
<企业经理:秘书电话>0755-21500000</企业经理:秘书电话>
                    
<企业经理:手机>13800008888</企业经理:手机>
                
</企业经理:电话>
            
</企业经理:企业经理>
        
</直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

我们注意到,在上面的代码中,“性别”前加了前缀“企业经理”。

若将manager.xsd修改如下,将attributeFormDefault 设置为"qualified",这样,局部属性“性别”不再属于命名空间targetNameSpace中。

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:经理="www.manager.com" targetNamespace="www.manager.com" elementFormDefault="unqualified" attributeFormDefault="unqualified">
    
<xs:element name="企业经理">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:姓名"/>
                
<xs:element ref="经理:电话"/>
            
</xs:sequence>
            
<xs:attribute name="性别">
                
<xs:simpleType>
                    
<xs:restriction base="xs:string">
                        
<xs:enumeration value="男"/>
                        
<xs:enumeration value="女"/>
                        
<xs:enumeration value="不男不女"/>
                    
</xs:restriction>
                
</xs:simpleType>
            
</xs:attribute>  
        
</xs:complexType>

    
</xs:element>
    
    
<xs:element name="姓名" type="xs:string"/>
    
<xs:element name="手机" type="xs:string"/>
    
<xs:element name="秘书电话" type="xs:string"/>
    
<xs:element name="电话">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:秘书电话"/>
                
<xs:element ref="经理:手机"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

这时,employee.xml中的“性别”属性前要去掉前缀“企业经理”,方能通过验证。如:

<?xml version="1.0" encoding="UTF-8"?>
<联系人:联系人列表 xmlns:联系人="www.shitou.com" xmlns:企业经理="www.manager.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="www.shitou.com
client.xsd www.manager.com manager.xsd"
>

    
<联系人:联系人>
        
<姓名>张三丰</姓名>
        
<ID>001</ID>
        
<公司>huawei</公司>
        
<EMAIL>zhang@huawei.com</EMAIL>
        
<电话>(0755)21530000</电话>
        
<联系人:地址>
            
<联系人:街道>高新南十一道</联系人:街道>
            
<联系人:城市>深圳市</联系人:城市>
            
<联系人:省份>广东</联系人:省份>
        
</联系人:地址>
        
<直接上司>
            
<企业经理:企业经理 性别="男">             
                
<企业经理:姓名>大刀王五</企业经理:姓名>

                
<企业经理:电话>
                    
<企业经理:秘书电话>0755-21500000</企业经理:秘书电话>
                    
<企业经理:手机>13800008888</企业经理:手机>
                
</企业经理:电话>
            
</企业经理:企业经理>
        
</直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

若将manager.xsd文件中局部属性“性别”改成全局属性,如下面代码所示,则“性别”属性还是属于命名空间targetNamespace中。

<?xml version="1.0" encoding="GB2312" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:经理="www.manager.com" targetNamespace="www.manager.com" elementFormDefault="unqualified" attributeFormDefault="unqualified">
    
<xs:element name="企业经理">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:姓名"/>
                
<xs:element ref="经理:电话"/>
            
</xs:sequence>
            
<xs:attribute ref="经理:性别"/>
        
</xs:complexType>
    
</xs:element>
    
    
<xs:attribute name="性别">
        
<xs:simpleType>
            
<xs:restriction base="xs:string">
                
<xs:enumeration value="男"/>
                
<xs:enumeration value="女"/>
                
<xs:enumeration value="不男不女"/>
            
</xs:restriction>
        
</xs:simpleType>
    
</xs:attribute>  
    
    
<xs:element name="姓名" type="xs:string"/>

    
<xs:element name="手机" type="xs:string"/>
    
<xs:element name="秘书电话" type="xs:string"/>
    
<xs:element name="电话">
        
<xs:complexType>
            
<xs:sequence>
                
<xs:element ref="经理:秘书电话"/>
                
<xs:element ref="经理:手机"/>
            
</xs:sequence>
        
</xs:complexType>
    
</xs:element>
</xs:schema>

此时,employee.xml文件中的属性“性别”前的前缀要加上,才能通过验证,如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<联系人:联系人列表 xmlns:联系人="www.shitou.com" xmlns:企业经理="www.manager.com"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="www.shitou.com
client.xsd www.manager.com manager.xsd"
>

    
<联系人:联系人>
        
<姓名>张三丰</姓名>
        
<ID>001</ID>
        
<公司>huawei</公司>
        
<EMAIL>zhang@huawei.com</EMAIL>
        
<电话>(0755)21530000</电话>
        
<联系人:地址>
            
<联系人:街道>高新南十一道</联系人:街道>
            
<联系人:城市>深圳市</联系人:城市>
            
<联系人:省份>广东</联系人:省份>
        
</联系人:地址>
        
<直接上司>
            
<企业经理:企业经理 企业经理:性别="男">             
                
<企业经理:姓名>大刀王五</企业经理:姓名>

                
<企业经理:电话>
                    
<企业经理:秘书电话>0755-21500000</企业经理:秘书电话>
                    
<企业经理:手机>13800008888</企业经理:手机>
                
</企业经理:电话>
            
</企业经理:企业经理>
        
</直接上司>
    
</联系人:联系人>
</联系人:联系人列表>

相信通过这么啰啰嗦嗦讲了一大堆,大家应该也基本明白了。还有一个属性xsi:noNamespaceSchemaLocation没有提到,大家上网查查。希望我的这点理解能对大家有所帮助。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值