关于XML和Schema约束的一些总结。
在学习XML约束的时候DTD约束还比较易懂(也可能是错觉),但是Schema约束的命名空间、引入,Schemalocation等比较难懂,总结一下最近自己查看其他专家的博客琢磨出来的东西
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" //这里可能有错误,该xsd文件多定义了一行默认的xmlSchema targetNamespace="http://www.example.org/web-app_2_5" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/web-app_2_5" elementFormDefault="qualified"> <xsd:element name="web-app"> <xsd:complexType> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:element name="servlet"> <xsd:complexType> <xsd:sequence> <xsd:element name="servlet-name"></xsd:element> <xsd:element name="servlet-class"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="servlet-mapping"> <xsd:complexType> <xsd:sequence> <xsd:element name="servlet-name"></xsd:element> <xsd:element name="url-pattern" maxOccurs="unbounded"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="welcome-file-list"> <xsd:complexType> <xsd:sequence> <xsd:element name="welcome-file" maxOccurs="unbounded"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> <xsd:attribute name="version" type="double" use="optional"></xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>
这是一个XSD约束文件,其中
xmlns与xmlns:nsd、xmlns:tns称为对命名空间的引用,xmlns称为默认命名空间,xmlns:前缀 称为显式命名空间,这两个有什么区别?
如果使用的是xmlns中定义的元素、属性、类型等成员直接使用即可,例如:<servlet>
如果使用的是xmlns:前缀中定义的元素、属性、类型等成员则需要在前面加上前缀,例如:<xsd:element>
“http://www.w3.org/2001/XMLSchema”是每个xsd文件必须有的命名空间,定义了element, attribute, complexType, group, simpleType等元素。
targetNamespace属性对本xsd文件所在的命名空间进行了定义,就好像java文件头上的“package cn.haiyisoft.xml”这个一样,说明了我这个java文档是在这个包下一样
xmlns与targetNamespace的关系,targetNamespace是定义了命名空间,而xmlns是将这个命名空间进行引入;xsd文件中定义了一个targetNameSpace后,其内部定义的元素,属性,类型等都属于该targetNameSpace,其自身或外部xsd文件使用这些元素,属性等都必须从定义的targetNameSpace中找。这就是xsd约束文件的一个很奇怪的地方,就算我某个成员定义在我文件内部,你想直接用也不行,必须用xmlns将我这个命名空间引入,如下例子:
xsd文件中定义了一个targetNameSpace后,其内部定义的元素,属性,类型等都属于该targetNameSpace,其自身或外部xsd文件使用这些元素,属性等都必须从定义的targetNameSpace中找。修改一下note.xsd,去除默认名称空间的声明,并添加一个复杂类型:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" elementFormDefault="qualified"> <xsd:element name="note"> <xsd:complexType> <xsd:sequence> <xsd:element name="to" type="xs:string"/> <xsd:element name="from" type="xs:string"/> <xsd:element name="heading" type="xs:string"/> <xsd:element name="body" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Student" type="stu"/> <xsd:complexType name="stu"> <xsd:sequence> <xsd:element name="Name" type="xs:string"/> <xsd:element name="Class" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
上述代码中,复杂类型stu是找不到的,因为你定义了一个名称空间"http://www.w3schools.com",该复杂类型存在于"http://www.w3schools.com"中,因此应该修改代码如下:
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns:student="http://www.w3schools.com" elementFormDefault="qualified"> <xsd:element name="note"> <xsd:complexType> <xsd:sequence> <xsd:element name="to" type="xs:string"/> <xsd:element name="from" type="xs:string"/> <xsd:element name="heading" type="xs:string"/> <xsd:element name="body" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Student" type="student:stu"/> <xsd:complexType name="stu"> <xsd:sequence> <xsd:element name="Name" type="xs:string"/> <xsd:element name="Class" type="xs:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
若自身并不使用重用定义的成员,仅供外部使用的话,则只定义targetNameSpace就可以,不用特别把自己的命名空间再次引入。
为什么xsd也有xmlns等属性呢?因为xsd也是一个xml文档啊,只不过后缀名变成了.xsd
关于elementFormDefault 有qualified和unqualified使用来规定是否只有全局成分才被定义在目标名称空间中。
<?xml version="1.0" encoding="UTF-8"?> <books xmlns="http://www.example.org/book" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/book book.xsd"> <book id="1001"> <name>Thinking in Java</name> <author>Bruce Eckel</author> <price>86.4</price> </book> <book id="1002"> <name>Head First 设计模式</name> <author>Freeman</author> <price>64.2</price> </book> <book id="1003"> <name>深入理解Java虚拟机</name> <author>周志明 </author> <price>59.2</price> </book> </books>
以上是一个xml文件
其中“http://www.w3.org/2001/XMLSchema-instance”是必须有的,它定义了一些成员,其中schemaLocation就是它其中定义的一个属性,所以根元素中的schemaLocation需要加xsi前缀
schemaLocation是一个类似于键值对的形式,由路径和文件名组成,以给解析器说明约束文件所在的位置,其中的路径必须和摸个xmlns引入的命名空间相同,也与此约束文件的targetNamespace的值相同
本文的参考来自于
1.https://blog.csdn.net/qq_38724991/article/details/76131614
2.https://blog.csdn.net/wanghuan203/article/details/9203621
3.https://blog.csdn.net/wanghuan203/article/details/9204337
4.https://blog.csdn.net/freelk/article/details/80869439#commentBox
5.https://blog.csdn.net/pzasdq/article/details/52592819
6.https://blog.csdn.net/ruizhe_hao/article/details/53432558
7.https://www.cnblogs.com/TIMHY/p/7780642.html
8.https://www.cnblogs.com/ihanliu/p/4718795.html