XML和Schema
2017-11-03 19:33:56
XML:Extensible Markup Language,也就是可扩展标记语言。XML工具使处理和转化信息变得十分容易和方便。
XML和HTML格式是古老的标记通用语言SGML的衍生语言。
尽管XML和HTML同宗同源,但是两者之间存在着重要的区别:
- 与HTML不同,XML是大小写敏感的,例如<H1>和<h1>是不同的XML标签。
- 在HTML中,如果从上下文可以分清哪里是段落或者列表项的结尾,那么结尾标签如</p>可以省略,而XML中结束标签绝对不能省略。
- 在XML中,只有单个标签而没有相对应的结束标签的元素必须以/结尾。这样解析器就不需要查找形如</p>的标签了。
- 在XML中,属性值必须用引号括起来。在HTML中,引号是可有可无的。例如,<applet code = "CodeDemo.class" width = 300>,这在HTML中是合法的,但是在XML中则是不被允许的,需要加上引号进行约束。所以在XML中应该写成<applet code = "CodeDemo.class" width = “300”>
- 在HTML中,属性名可以没有值。例如,<input type = "radio" cheacked>。在XML中所有的属性都必须要有属性值。比如,<input type = "radio" cheacked=“true”>
一、XML文档的结构
1、XML应该以一个文档头开始,例如:<?xml version="1.0" encoding="UTF-8"?>。严格来说,文档头是可选的,但是强烈建议使用文档头。
2、文档头之后通常是文档的文档类型定义(Document Type Definition,DTD)。文档的类型定义语句可以简化XML文档的解析,之后的DTD会被Schema替代,在Spring中也是采用的Schema进行文档的类型定义。
3、最后,XML文档的正文包含根元素,根元素包含一些其他的元素。例如
<?xml version="1.0"?> --文档头 <!DOCTYPE configuration ...> --文档的类型定义DTD <configuration> <title> <font> <name>Java</name> <size>36</size> </font> </title> ... </configuration>
元素可以有子元素(child element),文本或者两者皆有。在上述的例子中,font元素有两个子元素,它们是name和size。
[提示]:
- 在设计XML的时候,应该尽量使元素要么包含子元素,要么包含文本。换句话说,你应该避免以下的情况:
<font> Java <size>36</size> </font>
在XML规范里,这叫做混合式内容(mixed content)。如果包含混合式的内容那么在树形遍历子节点的时候就会出现需要进行判别的情况。所以要避免混合式内容,这样可以简化解析的过程。
- 何时使用元素,何时使用属性
这个问题在XML设计人员中存在着分歧。例如将font做如下的描述:
<font name="Java" size="36"/>
似乎要比下面的更简单一些:
<font> <name>Java</name> <size>36</size> </font>
但是属性的灵活性要差很多,假设你想把单位添加到size中去。如果使用属性,那么必须把单位添加到属性值中去:
<font name="Java" size="36 pt">
o no!这时候就需要对字符串“36 pt”进行解析,而这正是XML设计用来避免的麻烦。但是,如果把属性加到size元素中就会非常的方便:
<font> <name>Java</name> <size unit="pt">36</size> </font>
一个常用的经验法则是,属性值应该用来修改值的解释,而不是用来指定值。
在HTML中属性的使用规范很简单:凡是不显示在网页上的都是属性。
二、XML中的其他标记
- 字符引用
字符引用的形式是&#十进制值,或者&#x十六进制值。例如,字符a,a,或者a。
- 实体引用
实体引用的形式是&name,例如<;>;&;";&apos,都有预订的含义:小于,大于,&,引号,省略号。
- CDATA部分
CDATA部分用<![CDATA[...]]>来限定其界限。它们是字符数据的一种特殊形式。你可以用来囊括那些含有<,>,&之类的字符的字符串,而不用将它们解释为标记,例如:
<![CDATA[<&>是很常用的]]>。但是这里的字符串是不能包含]]>的,这也可以理解。
- 处理指令
处理指令是那么专门用来处理XML文档的应用程序中使用的指令,它们将用<? 和 ?>来限定其界限。例如:
<?xml version="1.0"?>
- 注释
注释是用<!-- -->限定的文本,例如:
<!-- This is a comment -->
另外,注释中是不能包含--的。注释只能用来给读者提供信息,其中绝对不能包含隐藏的命令,命令应该是用处理指令来实现的。
三、使用命名空间
Java中使用包来避免名字的冲突。这样程序员就可以在不同的包中使用相同的名字。XML中也有类似的命名空间(namespace)的机制,可以用于元素名和属性名。
名字空间是有统一资源标识符(Uniform Resource Identifier,URI)来标识的。其中HTTP的URL格式是最常用的。
在命名空间的URL所表示的位置上不需要有任何文档,XML解析器不会尝试去该处查看任何东西。然而,为了给遇到不熟悉的命名空间的程序员一些帮助,人们习惯与将解释该命名空间的文档放在URL上。
为什么使用HTTP的URL作为命名空间的标识符,这是因为这里的URL肯定是唯一的,其实这个道理和Java包名的命名为反向域名是同一个道理。
在 xml 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。
这个 xml文档携带着某个表格中的信息:
<table> <tr> <td>Apples</td> <td>Bananas</td> </tr> </table>
这个 XML 文档携带有关桌子的信息(一件家具):
<table> <name>African Coffee Table</name> <width>80</width> <length>120</length> </table>
假如这两个 XML 文档被一起使用,由于两个文档都包含带有不同内容和定义的 <table>
元素,就会发生命名冲突。XML 解析器无法确定如何处理这类冲突。
可以使用前缀来避免命名冲突,此文档带有某个表格中的信息:
<h:table> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table>
此 XML 文档携带着有关一件家具的信息:
<f:table> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table>
现在,命名冲突不存在了,这是由于两个文档都使用了不同的名称来命名它们的 <table>
元素 (<h:table>
和 <f:table>
)。通过使用前缀,我们创建了两种不同类型的 <table>
元素。
除了使用前缀,还可以使用命名空间(一个元素可以有多个命名空间,里面带前缀的是特地的命名空间,不带前缀的是默认命名空间),这个 XML 文档携带着某个表格中的信息:
<h:table xmlns:h="http://www.w3.org/TR/html4/"> <h:tr> <h:td>Apples</h:td> <h:td>Bananas</h:td> </h:tr> </h:table>
此 XML 文档携带着有关一件家具的信息:
<f:table xmlns:f="http://www.w3school.com.cn/furniture"> <f:name>African Coffee Table</f:name> <f:width>80</f:width> <f:length>120</f:length> </f:table>
与仅仅使用前缀不同,我们为 <table>
标签添加了一个 xmlns (xml namespace)属性,这样就为前缀赋予了一个与某个命名空间相关联的限定名称,下面是xml文件中xmlns属性的使用介绍,
XML Namespace (xmlns) 属性
XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法:
xmlns:namespace-prefix=”namespaceURI”
当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。
注意,用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。
四、Schema
XML Schema 是基于 XML 的 DTD 替代者。
XML Schema 描述 XML 文档的结构。
XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。
- 什么是Schema
XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。
- 定义可出现在文档中的元素
- 定义可出现在文档中的属性
- 定义哪个元素是子元素
- 定义子元素的次序
- 定义子元素的数目
- 定义元素是否为空,或者是否可包含文本
- 定义元素和属性的数据类型
- 定义元素和属性的默认值以及固定值
- 取代DTD的原因
我们认为 XML Schema 很快会在大部分网络应用程序中取代 DTD。
理由如下:
- XML Schema 可针对未来的需求进行扩展
- XML Schema 更完善,功能更强大
- XML Schema 基于 XML 编写
- XML Schema 支持数据类型
- XML Schema 支持命名空间
- XML Schema 支持数据类型
XML Schema 最重要的能力之一就是对数据类型的支持。
通过对数据类型的支持:
- 可更容易地描述允许的文档内容
- 可更容易地验证数据的正确性
- 可更容易地与来自数据库的数据一并工作
- 可更容易地定义数据约束(data facets)
- 可更容易地定义数据模型(或称数据格式)
- 可更容易地在不同的数据类型间转换数据
- XML Schema 使用 XML 语法
另一个关于 XML Schema 的重要特性是,它们由 XML 编写。
由 XML 编写 XML Schema 有很多好处:
- 不必学习新的语言
- 可使用 XML 编辑器来编辑 Schema 文件
- 可使用 XML 解析器来解析 Schema 文件
- 可通过 XML DOM 来处理 Schema
- 可通过 XSLT 来转换 Schema
- XML Schema 可保护数据通信
当数据从发送方被发送到接受方时,其要点是双方应有关于内容的相同的“期望值”。
通过 XML Schema,发送方可以用一种接受方能够明白的方式来描述数据。
一种数据,比如 "03-11-2004",在某些国家被解释为11月3日,而在另一些国家为当作3月11日。
但是一个带有数据类型的 XML 元素,比如:<date type="date">2004-03-11</date>,可确保对内容一致的理解,这是因为 XML 的数据类型 "date" 要求的格式是 "YYYY-MM-DD"。
-
XML Schema 可扩展
XML Schema 是可扩展的,因为它们由 XML 编写。
通过可扩展的 Schema 定义,您可以:
- 在其他 Schema 中重复使用您的 Schema
- 创建由标准类型衍生而来的您自己的数据类型
- 在相同的文档中引用多重的 Schema
-
形式良好是不够的
我们把符合 XML 语法的文档称为形式良好的 XML 文档,比如:
- 它必须以 XML 声明开头
- 它必须拥有唯一的根元素
- 开始标签必须与结束标签相匹配
- 元素对大小写敏感
- 所有的元素都必须关闭
- 所有的元素都必须正确地嵌套
- 必须对特殊字符使用实体
即使文档的形式良好,仍然不能保证它们不会包含错误,并且这些错误可能会产生严重的后果。
请考虑下面的情况:您订购的了 5 打激光打印机,而不是 5 台。通过 XML Schema,大部分这样的错误会被您的验证软件捕获到。
- 如何使用XSD
XML 文档可对 DTD 或 XML Schema 进行引用。
一个简单的 XML 文档:
请看这个名为 "note.xml" 的 XML 文档:
<?xml version="1.0"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
DTD 文件
下面这个例子是名为 "note.dtd" 的 DTD 文件,它对上面那个 XML 文档的元素进行了定义:
<!ELEMENT note (to, from, heading, body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
第 1 行定义 note 元素有四个子元素:"to, from, heading, body"。
第 2-5 行定义了 to, from, heading, body 元素的类型是 "#PCDATA"。
XML Schema
下面这个例子是一个名为 "note.xsd" 的 XML Schema 文件,它定义了上面那个 XML 文档( "note.xml" )的元素:
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
note 元素是一个复合类型,因为它包含其他的子元素。其他元素 (to, from, heading, body) 是简易类型,因为它们没有包含其他元素。
对 DTD 的引用
此文件包含对 DTD 的引用:
<?xml version="1.0"?> <!DOCTYPE note SYSTEM "http://www.w3school.com.cn/dtd/note.dtd"> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
对 XML Schema 的引用
此文件包含对 XML Schema 的引用:
<?xml version="1.0"?> <note xmlns="http://www.w3school.com.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3school.com.cn note.xsd"> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
- 对Schema的引用的理解
首先,需要注意的是Schema也是个xml文件,所以它也有自己的命名空间。
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified"> ... ... </xs:schema>
其中,
xmlns:xs="http://www.w3.org/2001/XMLSchema"
表示给这个xml中schema定义了一个命名空间http://www.w3.org/2001/XMLSchema
,xs为使用时的前缀。
targetNamespace="http://www.w3school.com.cn"
显示被此 schema 定义的元素 (note, to, from, heading, body) 来自命名空间: "http://www.w3school.com.cn"
,即这个schema是为”http://www.w3school.com.cn“命名空间所提供约束的,也就是被声明为http://www.w3school.com.cn命名空间的xml文件所引用。
xmlns="http://www.w3school.com.cn"
指出schema 中元素的默认的命名空间是 "http://www.w3school.com.cn"
。
此 XML 文档含有对 XML Schema 的引用:
<?xml version="1.0"?> <note xmlns="http://www.w3school.com.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3school.com.cn note.xsd"> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
其中,
xmlns="http://www.w3school.com.cn"
定义了该xml元素的默认命名空间为http://www.w3school.com.cn
。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
又定义了一个命名空间(官方叫XML Schema 实例命名空间),和前缀xsi关联,定义这个命名空间的原因是,schemaLocation 属性在这个命名空间下,也就是说,只有先定义了这个命名空间,才能使用schemaLocation 属性。
xsi:schemaLocation="http://www.w3school.com.cn note.xsd"
设置xsi前缀代表的命名空间中的一个属性schemaLocation为"http://www.w3school.com.cn note.xsd"
(XML Schema 实例命名空间下的schemaLocation属性,该属性貌似被schema 验证器读取?名称是固定的?)。
此属性有两个值,第一个值是需要使用的命名空间,第二个值是供命名空间使用的 XML schema 的位置(note.xsd就是根元素为schema的那个xml文件),其实也就是表示命名空间为http://www.w3school.com.cn的xml元素(文件)对应的Schema的位置(文件)为note.xsd,所以Schema中的targetNamespace属性值必须和xsi:schemaLocation属性的第一个值相同,这里都为http://www.w3school.com.cn(需要引用schema的xml中定义的命名空间为第一个值,表示它要被shema限制)。