在前面的xml模式文档(xml:Schema)详解博文中讲解了大量xml和schema的知识,量比较大,可能有点晕。现在来做点小实验来验证下这些知识。
首先note.xsd文件
- <?xml version="1.0"?>
- <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://www.w3schools.com"
- xmlns="http://www.w3schools.com"
- elementFormDefault="qualified">
- <xsd:element name="note">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="to" type="xsd:string"/>
- <xsd:element name="from" type="xsd:string"/>
- <xsd:element name="heading" type="xsd:string"/>
- <xsd:element name="body" type="xsd:string"/>
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- <?xml version="1.0"?>
- <note xmlns="http://www.w3schools.com"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.w3schools.com note.xsd">
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Don't forget me this weekend!</body>
- </note>
- 验证通过,如果将note.xml中的<to>Tove</to>改为<to1>Tove</to1>则报错,说明验证是起作用的
详解中讲到:
对于任何一个XML Schema定义文档(XSD)都有一个最顶层的schema (XSD)元素。而且该schema (XSD)元素定义必须包含这个名称空间:
http://www.w3.org/2001/XMLSchema
。即此名称空间是由XML模式规范定义的标准名称空间-所有XML模式元素必须属于该名称空间。即note.xsd中<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 名称空间是不能更改的(xsd前缀是可以更改的)
验证,将上文note.xsd中该行改为:<xsd:schema xmlns:xsd="http://www.w3.org/2001",
报错:The namespace of element 'schema' must be from the schema namespace.说明详解中将的是对的
将前缀xsd全部改为xs也是验证通过的
详解中:
-
此片段:targetNamespace="http://www.w3schools.com",表明此schema (note, to, from, heading, body)定义的元素来自于"http://www.w3schools.com"名称空间。这个targetNamespace属性表示了该schema所对应的名称空间的URI。也就是说在引用该Schema的其它文档(包括自身文档)中要声明名称空间,其URI应该是targetNamespace的属性值。例如在这里因为要用到note.xsd自己定义的扩展数据类型(note, to, from, heading, body),所以也声明了名称空间xmlns="http://www.w3schools.com"。而且该名称空间是默认名称空间(没有前缀)。targetNamespace属性为在模式中显式创建的所有新类型均声明了XML名称空间。
-
note.xml文件中默认命名空间为"http://www.w3schools.com",由上文知,它应该是与note.xsd文件的targetNamespace属性值相同。
将note.xml默认命名空间改为"http://www.w3schools.com1",
验证报错:未知的对象note.
xsi:schemaLocation属性的值由一个URI引用对组成,两个URI之间以空白符分隔。第一个URI是名称空间的名字,第二个URI给出模式文档的位置,模式处理器将从这个位置读取模式文档,该模式文档的目标名称空间必须与第一个URI相匹配。
验证:(1),将note.xml中
-
- <note xmlns="http://www.w3schools.com"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.w3schools.com note.xsd">
- 改为
- <note xmlns="http://www.w3schools.com"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.w3schools1.com note.xsd">
- 验证报错:Schema in note.xsd has a different target namespace from the one specified in the instance document http://www.w3schools1.com
详解中:
重点理解Schema文档使用自身定义类型
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"中,
验证结果:Type not found in :stu
因此应该修改代码添加一行:<xmlns="http://www.w3schools.com">
然后验证通过。
xml文件中的命名空间是否是任意的呢,例如我把上文中的"http://www.w3schools.com"改为"http://www.w3schools.com1"可以吗。
理论上来说是可以的,命名空间只是一个标识。
将上文中的"http://www.w3schools.com"都改为"http://www.w3schools.com1",验证一下
验证结果:通过
- <note xmlns="http://www.w3schools.com"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.w3schools.com note.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 改为xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance1"
验证结果:no DTD found !验证是不通过的。
查资料看了下,
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"中xsi的意思是 :
本xml文件中要用到某些来自xsi代表的“http://www.w3.org/2001/XMLSchema-instance”这个命名空间的元素
比如用来引入无命名空间schema文件的noNamespaceSchemaLocation="XXX";
以及引入自带命名空间的schema文件的schemaLocation="XXX"这些元素。
本xml文件中要用到某些来自xsi代表的“http://www.w3.org/2001/XMLSchema-instance”这个命名空间的元素
比如用来引入无命名空间schema文件的noNamespaceSchemaLocation="XXX";
以及引入自带命名空间的schema文件的schemaLocation="XXX"这些元素。
这里使用了schemaLocation元素,所以必须引入“http://www.w3.org/2001/XMLSchema-instance”命名空间
这些元素是包含在“http://www.w3.org/2001/XMLSchema-instance”命名空间中的,所有的xml文件只要引用这些元素 就要引入这个命名空间,前缀可以修改,但命名空间不能改。
这些元素是包含在“http://www.w3.org/2001/XMLSchema-instance”命名空间中的,所有的xml文件只要引用这些元素 就要引入这个命名空间,前缀可以修改,但命名空间不能改。
总结起来
note.xsd文件
- <?xml version="1.0"?>
- <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- targetNamespace="http://www.w3schools.com"
- xmlns="http://www.w3schools.com"
- elementFormDefault="qualified">
- <xsd:element name="note">
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="to" type="xsd:string"/>
- <xsd:element name="from" type="xsd:string"/>
- <xsd:element name="heading" type="xsd:string"/>
- <xsd:element name="body" type="xsd:string"/>
- </xsd:sequence>
- </xsd:complexType>
- </xsd:element>
- </xsd:schema>
- 元素:schema对应的命名空间固定:"http://www.w3.org/2001/XMLSchema"
- <?xml version="1.0"?>
- <note xmlns="http://www.w3schools.com"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.w3schools.com note.xsd">
- <to>Tove</to>
- <from>Jani</from>
- <heading>Reminder</heading>
- <body>Don't forget me this weekend!</body>
- </note>
当然,如果不要求xml验证,只要求格式良好,则命名空间没什么限制。