一个 XML 文档一旦有了约束,那么这个 XML 文档就只能使用约束中创建的元素及属性。如果约束没有创建
<a>
元素,那么 XML 文档就不能使用<a>
元素。 XML 有两种约束:DTD 和 Schema,这二者都是用来描述 XML 文档结构,限定文档的数据类型的, 只是做法上不一样。
一个 XML 文档一旦有了约束,那么这个 XML 文档就只能使用约束中创建的元素及属性。
如果约束没有创建 <a>
元素,那么 XML 文档就不能使用 <a>
元素。
XML 有两种约束:DTD 和 Schema,这二者都是用来描述 XML 文档结构,限定文档的数据类型的, 只是做法上不一样。
DTD 和 XML Schema 之间的关键区别在于 XML Schema 使用基于 XML 的语法,而 DTD 具有从 SGML DTD 保留的独特语法。虽然 DTD 经常因为需要学习新的语法而受到批评,但语法本身非常简洁。XML Schema 则相反,它很冗长,但也使用标签和 XML,因此 XML 的作者应该发现 XML Schema 的语法不那么令人生畏。
DTD : 文档类型定义(Document Type Definition)是一套关于标记符的语法规则。
DTD 主要分为内部定义和外部定义:
内部 DTD 的定义,需要在顶部加入,语法如下:
<!DOCTYPE 根元素 [元素声明]>
我们来看实例代码 book.xml:
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书>
<书名>深入理解Java虚拟机</书名>
<售价>129.00</售价>
</书>
<书>
<书名>Java并发编程实战</书名>
<售价>97.00</售价>
</书>
</书架>
与之对应的 DTD 约束文档 book.dtd,代码如下:
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
对 book.dtd 文档所规定的约束详细解释如下:
<!ELEMENT…>
语句定义了一个元素,其中 “书架” 是元素的名称,“(书+)” 表示书架元素中有一个或者多个书元素,字符 +
用来表示它所修饰的成分必须出现一次或者多次;那么,创建 DTD 文件步骤:
<!ELEMENT>
;
<!ELEMENT 元素名称 (#PCDATA)>
<!ELEMENT 元素名称 (子元素+)>
或 <!ELEMENT 元素名称 (子元素,子元素,……)>
有了 DTD 文件,如果想使用 DTD 文件来约束 XML 文档,必须在 XML 文档中引入 DTD 文件。
在 XML 文档中引入外部 DTD 文件有两种方式,具体如下:
<!DOCTYPE 根元素名称 SYSTEM "外部DTD文件URI">
<!DOCTYPE 根元素名称 PUBLIC "DTD名称" "外部DTD文件URI">
在上述两种引入 DTD 文件的方式中:
在XML中直接嵌入DTD定义语句的完整语法格式如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE 根元素名 [
DTD定义语句
……
]>
暂略
同 DTD 一样,XML Schema(XML Schema Definition,XSD,XML Schema定义)也是一种用于定义和描述 XML 文档结构与内容的模式语言,它的出现克服了 DTD 的局限性。
通过 XML Schema 与 DTD 的比较,将 XML Schema 所具有的一些显著优点进行列举,具体如下:
通过上面的比较可以发现,XML Schema 的功能比 DTD 强大很多,但相应的语法也比DTD复杂很多。Schema 是基于 XML 编写的,XML Schema 约束文件本身就是一个 XML 文档(文件后缀名为.xsd),文件内的代码要符合 XML 语法规范。
一个 XML 文档可以引入多个 Schema 约束文档,但是,由于约束文档中的元素或属性都是自定义的,因此,在 XML 文档中,极有可能出现代表不同含义的同名元素或属性,导致名称发生冲突。为此,在 XML 文档中,提供了名称空间,它可以唯一标识一个元素或者属性。
这就好比咱们系有两个同名的同学,如果老师要找那个同学,就得给他们的名字前面加个前缀,XXX 班的某某某。这个 “XXX班” 就相当于一个名称空间。
在使用名称空间时,首先必须声明名称空间。名称空间的声明就是在 XML 实例文档中为某个模式文档的名称空间指定一个临时的简写名称(起个别名),它通过一系列的保留属性来声明,这种属性的名字必须是以 “xmlns” 或者以 “xmlns:” 作为开始。它与其它任何 XML 属性一样,都可以通过直接或者使用默认的方式给出。
名称空间声明的语法格式如下所示:
<元素名称 xmlns:prefixname="URI">
在上述语法格式中,元素名称指的是在哪一个元素上声明名称空间,在这个元素上声明的名称空间适用于声明它的元素和属性,以及该元素中嵌套的所有元素及其属性。“xmlns:prefixname” 指的是该元素的属性名,它所对应的值是一个 URI 引用,用来标识该名称空间的名称。
我们来修改 book.xm l文件:
<?xml version="1.0" encoding="UTF-8"?>
<xs:书架 xmlns:xs="http://www.example.org/book/schema"
xmlns="http://www.w3.org/2001/XMLSchema-instance">
<xs:书>
<xs:书名>深入理解Java虚拟机</xs:书名>
<xs:售价>129.00</xs:售价>
</xs:书>
</xs:书架>
名称空间的使用就是将一个前缀(xs)绑定到代表某个名称空间的 URI(http://www.example.org/book/schema)上。
然后将前缀添加到元素名称前面来说明该元素属于哪个 Schema 文档。
如果一个 XML 文档有很多元素,而且这些元素都在同一个名称空间,这时,给每个元素名称都添加一个前缀将是一件非常烦琐的事情。
这时,可以使用默认的名称空间,默认名称空间声明时不需要加 “别名”,使用这些元素时,也不用加前缀。
<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns=http://www.example.org/book/schema>
<书>
<书名>深入理解Java虚拟机</xs:书名>
<售价>129.00</xs:售价>
</书>
</书架>
如果想通过 XML Schema 文件对某个 XML 文档进行约束,必须将 XML 文档与 Schema 文件进行关联。在 XML 文档中引入 Schema 文件有两种方式:
上面的书架 “book.xml” 文件对应的 XML Schema 约束文件 “book.xsd”:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/book"
xmlns:tns="http://www.example.org/book"
elementFormDefault="qualified">
<element name="书架">
<complexType>
<sequence>
<element name="书">
<complexType>
<sequence>
<element name="书名" type="string" />
<element name="售价" type="string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
那么,我们需要在 XML 文档中的根节点中使用 schemaLocation 属性来指定 Schema 文件。schemaLocation 属性有两个值:
第一个值是需要使用的名称空间;
第二个值是供命名空间使用的 XML Schema 文件的路径;
两者之间用空格分隔。
<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns="http://www.example.org/book"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/book book.xsd ">
<书>
<书名>深入理解Java虚拟机</xs:书名>
<售价>129.00</xs:售价>
</书>
</书架>
如果要使用名称空间引入多个 “XML Schema” 文档。修改 “book.xml” 文件:
<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns="http://www.example.org/book"
xmlns:demo="http://www.example.org/demo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/book book.xsd
http://www.example.org/demo demo.xsd ">
<书>
<书名>深入理解Java虚拟机</xs:书名>
<售价>129.00</xs:售价>
</书>
</书架>
如果 book.xsd 与引用它的 XML 文件位于同一个目录中,我们可以不使用名称空间来引入 Schema,book.xsd 中不需要定义 targetNamespace(目标名称空间)和 xmlns:tns(所在名称空间)了,book.xsd 代码:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<element name="书架">
<complexType>
<sequence>
<element name="书">
<complexType>
<sequence>
<element name="书名" type="string" />
<element name="售价" type="string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
修改 book.xml 文件,在 book.xml 中也不需要指定默认名称空间了。
<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="book.xsd">
<书>
<书名>深入理解Java虚拟机</xs:书名>
<售价>129.00</xs:售价>
</书>
</书架>
“noNamespaceSchemaLocation” 是一个在标准名称空间(http://www.w3.org/2001/XMLSchema-instance)里面定义好的属性,用于指定 “book.xsd” 文档位置。
暂略