关于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

原文地址:https://www.cnblogs.com/JSD1207ZX/p/10162438.html