XML 树结构
XML 文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶"。
树结构是通常被称为 XML 树,并且可以很容易地描述任何 XML 文档。
通过采用树状结构,可以知道所有从根开始的后续的分行及支行。
实例
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>...</to>
<from>...</from>
<heading>...</heading>
<body>......</body>
</note>
第一行是 XML 声明。
它定义 XML 的版本(1.0)和所使用的编码(ISO-8859-1 = Latin-1/西欧字符集)。
下一行描述文档的根元素
<note>
接下来 4 行描述根的 4 个子元素(to, from, heading 以及 body):
<to>...</to>
<from>...</from>
<heading>...</heading>
<body>......</body>
最后一行定义根元素的结尾:
</note>
XML 文档形成一种树结构
XML 文档必须包含根元素。该元素是所有其他元素的父元素。
XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。
所有的元素都可以有子元素:
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
父、子以及同胞等术语用于描述元素之间的关系。
父元素拥有子元素。相同层级上的子元素成为同胞。
所有的元素都可以有文本内容和属性。
实例:
<bookstore>
<book category="xxx">
<title lang="en">...</title>
<author>...</author>
<year>....</year>
<price>...</price>
</book>
<book category="yyy">
<title lang="en">...</title>
<author>...</author>
<year>....</year>
<price>...</price>
</book>
<book category="zzz">
<title lang="en">...</title>
<author>...</author>
<year>....</year>
<price>...</price>
</book>
</bookstore>
实例中的根元素是 <bookstore>。文档中的所有 <book> 元素都被包含在 <bookstore> 中。
<book> 元素有 4 个子元素:<title>、<author>、<year>、<price>。
XML 语法
xml声明
一个xml文档必须要有第一行的声明和它的文档元素的描述信息。
<?xml version="1.0" encoding="UTF-8"?>
注:xml声明一般是xml文档的第一行;xml声明由以下几个部分组成:
所有的 XML 元素都必须有一个关闭标签
在 XML 中,省略关闭标签是非法的。所有元素都必须有关闭标签:
<?xml version="1.0" encoding="UTF-8" ?>
<p>......</p>
注释:声明不是 XML 文档本身的一部分,它没有关闭标签。
XML 标签对大小写敏感
必须使用相同的大小写来编写打开标签和关闭标签:
<message>This is correct</message>
XML 必须正确嵌套
在 XML 中,所有元素都必须彼此正确地嵌套:
<b><i>......</i></b>
XML 文档必须有根元素
XML 文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
XML 属性值必须加引号
XML 元素拥有属性(名称/值的对)。
在 XML 中,XML 的属性值必须加引号。
<note date="../../....">
<to>...</to>
<from>...</from>
</note>
实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:
<message>if ... < 1000 then</message>
用实体引用来代替 "<" 字符:
<message>if ... < 1000 then</message>
在 XML 中,有 5 个预定义的实体引用:
实体引用 | 字符 | |
< | < | less than |
> | > | greater than |
& | & | ampersand |
' | ' | apostrophe |
" | " | quotation mark |
注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的。
XML 中的注释
<!-- This is a comment -->
在 XML 中,空格会被保留
在 XML 中,文档中的空格不会被删减。
XML 以 LF 存储换行
XML 以 LF 存储换行。
XML 元素
XML 元素指的是从(且包括)开始标签直到(且包括)结束标签的部分。
一个元素可以包含:
- 其他元素
- 文本
- 属性
- 或混合以上所有...
<bookstore>
<book category="xxx">
<title>x</title>
<author>x</author>
<year>xxxx</year>
<price>xxx</price>
</book>
<book category="yyy">
<title>y</title>
<author>y</author>
<year>yyyy</year>
<price>yyy</price>
</book>
</bookstore>
上面的实例中,<bookstore> 和 <book> 都有元素内容,因为他们包含其他元素。<book> 元素也有属性(category="x")。<title>、<author>、<year> 和 <price> 有文本内容,因为他们包含文本。
XML 命名规则
XML 元素必须遵循以下命名规则:
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml(或者 XML、Xml 等等)开始
- 名称不能包含空格
可使用任何名称,没有保留的字词。
XML 元素是可扩展的
XML 元素是可扩展,以携带更多的信息。
实例
<note>
<to>y</to>
<from>x</from>
<body>......</body>
</note>
假设创建了一个应用程序,可将 <to>、<from> 以及 <body> 元素从 XML 文档中提取出来,并产生以下的输出:
MESSAGE
To: y
From: x。。。。。。
如果添加一些额外的信息:
<note>
<date>xxxx-xx-xx</date>
<to>y</to>
<from>x</from>
<heading>..</heading>
<body>......</body>
</note>
那么这个应用程序会中断或崩溃吗?
不会。这个应用程序仍然可以找到 XML 文档中的 <to>、<from> 以及 <body> 元素,并产生同样的输出。
XML 的优势之一,就是可以在不中断应用程序的情况下进行扩展。
XML 属性
XML 属性必须加引号
属性值必须被引号包围,不过单引号和双引号均可使用。
<person x="xxx">
<person x='xxx'>
如果属性值本身包含双引号,您可以使用单引号:
<person x='x1 "x2" x3'>
或者您可以使用字符实体:
<person x="x1 "x2" x3">
XML 元素 vs. 属性
实例:
<person x="xxx">
<firstname>x</firstname>
<lastname>y</lastname>
</person>
<person>
<x>xxx</x>
<firstname>x</firstname>
<lastname>y</lastname>
</person>
在第一个实例中,x 是一个属性。
在第二个实例中,x 是一个元素。
两个实例都提供相同的信息。
在 XML 中,您应该尽量避免使用属性。如果信息感觉起来很像数据,那么请使用元素吧。
避免 XML 属性?
使用属性而引起的一些问题:
- 属性不能包含多个值(元素可以)
- 属性不能包含树结构(元素可以)
- 属性不容易扩展
属性难以阅读和维护。
尽量使用元素来描述数据。
仅仅使用属性来提供与数据无关的信息。
针对元数据的 XML 属性
有时候会向元素分配 ID 引用。
这些 ID 索引可用于标识 XML 元素,它起作用的方式与 HTML 中 id 属性是一样的。
实例
<messages>
<note id="1">
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
<note id="2">
<to>x</to>
<from>y</from>
<heading>x: xxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
</messages>
上面的 id 属性仅仅是一个标识符,用于标识不同的便签。它并不是便签数据的组成部分。
元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素。
XML 属性需要遵循的规则:
- 属性名称不能在同一起始标签或空元素标签中出现一次
- 一个属性必须使用属性表声明的文档类型定义的声明
- 属性值不能包含直接或间接的实体引用外部实体
- 任何实体的替换文本称为直接或间接的属性值中不能包含任何小于号
XML DTD
XML 验证
DTD 中文意思为“文档类型定义”。
拥有正确语法的 XML 被称为"形式良好"的 XML。
通过 DTD 验证的XML是"合法"的 XML。
形式良好的 XML 文档
语法规则:
- XML 文档必须有一个根元素
- XML元素都必须有一个关闭标签
- XML 标签对大小写敏感
- XML 元素必须被正确的嵌套
- XML 属性值必须加引号
验证 XML 文档
合法的 XML 文档是"形式良好"的 XML 文档,符合文档类型定义(DTD)的规则:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE note SYSTEM "Note.dtd">
<note>
<to>y</to>
<from>x</from>
<heading>xxx</heading>
<body>xxxxxx</body>
</note>
DOCTYPE 声明是对外部 DTD 文件的引用。
XML DTD
DTD 的目的是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构:
<!DOCTYPE note
[
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
XML Schema
基于 XML 的 DTD 代替者,它名为 XML Schema:
<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>
查看 XML 文件
查看 XML 文件
XML 文档将显示为代码颜色化的根以及子元素。通过点击元素左侧的加号(+)或减号( - ),可以展开或收起元素的结构。要查看原始的 XML 源(不包括 + 和 - 符号),选择"查看页面源代码"或从浏览器菜单"查看源文件"。
查看无效的 XML 文件
如果一个错误的XML文件被打开,浏览器会报告错误。
为什么 XML 显示这个样子?
XML 文档不会携带有关如何显示数据的信息。
在没有任何有关如何显示数据的信息的情况下,大多数的浏览器都会仅仅把 XML 文档显示为源代码。
DTD 简介
文档类型定义(DTD)可定义合法的XML文档构建模块。
它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
内部的 DOCTYPE 声明
DTD 被包含在 XML 源文件中,应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE root-element [element-declarations]>
实例
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
注释:
- !DOCTYPE note (第二行)定义此文档是 note 类型的文档。
- !ELstrongENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"
- !ELstrongENT to (第四行)定义 to 元素为 "#PCDATA" 类型
- !ELstrongENT from (第五行)定义 frome 元素为 "#PCDATA" 类型
- !ELstrongENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
- !ELstrongENT body (第七行)定义 body 元素为 "#PCDATA" 类型
外部文档声明
DTD 位于 XML 源文件的外部,应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE root-element SYSTEM "filename">
这个实例有一个外部的 DTD:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
包含 DTD 的 "note.dtd" 文件:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
为什么使用 DTD?
通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
您还可以使用 DTD 来验证您自身的数据。
DTD 构建模块
XML 文档构建模块
所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
元素
元素是 XML 以及 HTML 文档的主要构建模块。
HTML 元素的例子是 "body" 和 "table"。
XML 元素的例子是 "note" 和 "message" 。
元素可包含文本、其他元素或者是空的。
空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。
实例:
<body>some text</body>
<message>some text</message>
属性可提供有关元素的额外信息。
属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。
"img" 元素拥有关于源文件的额外信息:
<img src="computer.gif" />
元素的名称是 "img"。属性的名称是 "src"。属性的值是 "computer.gif"。
由于元素本身为空,它被一个 " /" 关闭。
PCDATA
PCDATA 的意思是被解析的字符数据。
把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
DTD 元素
在 DTD 中,元素的作用是约束标记,用元素声明来定义一个标记,元素声明以 “<!ELEMENT” 开始,以 “>” 结束。
在一个 DTD 中,元素通过元素声明来进行声明。
声明一个元素
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:
<!ELEMENT element-name category>
或
<!ELEMENT element-name (element-content)>
空元素
空元素通过类别关键词EMPTY进行声明:
<!ELEMENT element-name EMPTY>
实例:
<!ELEMENT br EMPTY>
XML example:
<br />
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:
<!ELEMENT element-name (#PCDATA)>
实例:
<!ELEMENT from (#PCDATA)>
带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT element-name ANY>
实例:
<!ELEMENT note ANY>
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT element-name (child1)>
或
<!ELEMENT element-name (child1,child2,...)>
实例:
<!ELEMENT note (to,from,heading,body)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在
一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。
"note" 元素的完整声明是:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
声明只出现一次的元素
<!ELEMENT element-name (child-name)>
实例:
<!ELEMENT note (message)>
声明:message 子元素必须出现一次,并且必须只在 "note" 元素中出现一次。
声明最少出现一次的元素
<!ELEMENT element-name (child-name+)>
实例:
<!ELEMENT note (message+)>
加号(+)声明:message 子元素必须在 "note" 元素内出现至少一次。
声明出现零次或多次的元素
<!ELEMENT element-name (child-name*)>
实例:
<!ELEMENT note (message*)>
星号(*)声明了:子元素 message 可在 "note" 元素内出现零次或多次。
声明出现零次或一次的元素
<!ELEMENT element-name (child-name?)>
实例:
<!ELEMENT note (message?)>
问号(?)声明:子元素 message 可在 "note" 元素内出现零次或一次。
声明"非.../即..."类型的内容
实例:
<!ELEMENT note (to,from,header,(message|body))>
声明了:"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素即 "body" 元素。
声明混合型的内容
实例:
<!ELEMENT note (#PCDATA|to|from|header|message)*>
声明了:"note" 元素可包含出现零次或多次的 PCDATA、"to"、"from"、"header" 或者 "message"。
提示:以上几种类型都允许在元素的起始标记中使用属性。
注意:在DTD中有一个原则,没有明确声明就是禁止,并且同名的元素只能声明一次。
DTD 属性
任何标记的属性都必须在 DTD 文档中进行声明,并且必须都要通过关键字进行说明!
在 DTD 中,属性通过 ATTLIST 声明来进行声明。
声明属性
语法:
<!ATTLIST element-name attribute-name attribute-type attribute-value>
DTD 实例:
<!ATTLIST payment type CDATA "check">
XML 实例:
<payment type="check" />
属性类型的选项:
类型 | 描述 |
CDATA | 值为字符数据 |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
默认属性值使用下列值 :
值 | 解释 |
值 | 属性的默认值 |
#REQUIRED | 属性值是必需的 |
#IMPLIED | 属性不是必需的 |
#FIXED value | 属性值是固定的 |
默认属性值
DTD:
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
合法的 XML:
<square width="100" />
"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。
如果宽度没有被设定,其默认值为0 。
#REQUIRED
语法
<!ATTLIST element-name attribute-name attribute-type #REQUIRED>
实例
DTD:
<!ATTLIST person number CDATA #REQUIRED>
合法的 XML:
<person number="11111" />
假如不希望强制作者包含属性,并且您没有默认值选项的话,请使用关键词 #IMPLIED。
#IMPLIED
语法
<!ATTLIST element-name attribute-name attribute-type #IMPLIED>
实例
DTD:
<!ATTLIST contact fax CDATA #IMPLIED>
合法的 XML:
<contact fax="111-445566" />
<contact />
假如不希望强制作者包含属性,并且您没有默认值选项的话,请使用关键词 #IMPLIED。
#FIXED
语法
<!ATTLIST element-name attribute-name attribute-type #FIXED "value">
实例
DTD:
<!ATTLIST sender company CDATA #FIXED "Microsoft">
合法的 XML:
<sender company="Microsoft" />
如果希望属性拥有固定的值,并不允许作者改变这个值,请使用 #FIXED 关键词。
如果使用了不同的值,XML 解析器会返回错误。
列举属性值
语法
<!ATTLIST element-name attribute-name (en1|en2|..) default-value>
实例
DTD:
<!ATTLIST payment type (check|cash) "cash">
XML 例子:
<payment type="check" />
<payment type="cash" />
如果希望属性值为一系列固定的合法值之一,请使用列举属性值。
DTD 实体
在 DTD 中进行实体声明的时候,将使用 ENTITY 关键字来声明。
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
- 实体引用是对实体的引用。
- 实体可在内部或外部进行声明。
一个内部实体声明
语法
<!ENTITY entity-name "entity-value">
实例
DTD 实例:
<!ENTITY writer "xxxxxx">
<!ENTITY copyright "Copyright yyyyyy">
XML 实例:
<author> &writer; ©right; </author>
注意: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
提示:内部实体在 XML 文档内部定义,实体的内容在声明中给出。内部实体都是已分析的实体,它们没有单独的物理存储对象。
一个外部实体声明
语法
<!ENTITY entity-name SYSTEM "URI/URL">
DTD 实例:
<!ENTITY writer SYSTEM "//www.xxxxxx.cn/entities.dtd">
<!ENTITY copyright SYSTEM "//www.yyyyyy.cn/entities.dtd">
XML 实例:
<author> &writer; ©right; </author>
提示:外部实体在单独的(外部)文件中定义,外部实体可以是已分析实体,也可以是未分析实体。
DTD 验证
通过 DTD,你可以对您的 XML 文件进行验证。
通过 XML 解析器进行验证
当您试图打开某个 XML 文档时,XML 解析器有可能会产生错误。
通过访问 parseError 对象,就可以取回引起错误的确切代码、文本甚至所在的行。
注意: load() 方法用于文件,而 loadXML() 方法用于字符串。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>XML</title>
</head>
<body>
<h3>
This demonstrates a parser error:
</h3>
<script>
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.validateOnParse="true";
xmlDoc.load("note_dtd_error.xml");
document.write("<br>Error Code: ");
document.write(xmlDoc.parseError.errorCode);
document.write("<br>Error Reason: ");
document.write(xmlDoc.parseError.reason);
document.write("<br>Error Line: ");
document.write(xmlDoc.parseError.line);
</script>
</body>
</html>
关闭验证
通过把 XML 解析器的 validateOnParse 设置为 "false",就可以关闭验证。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>XML</title>
</head>
<body>
<script>
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.validateOnParse="false";
xmlDoc.load("note_dtd_error.xml");
document.write("<br>Error Code: ");
document.write(xmlDoc.parseError.errorCode);
document.write("<br>Error Reason: ");
document.write(xmlDoc.parseError.reason);
document.write("<br>Error Line: ");
document.write(xmlDoc.parseError.line);
</script>
</body>
</html>
XML Schemas 简介
XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。
XML Schema:
- 定义可出现在文档中的元素
- 定义可出现在文档中的属性
- 定义哪个元素是子元素
- 定义子元素的次序
- 定义子元素的数目
- 定义元素是否为空,或者是否可包含文本
- 定义元素和属性的数据类型
- 定义元素和属性的默认值以及固定值
XML Schema 是 DTD 的继任者
理由:
- XML Schema 可针对未来的需求进行扩展
- XML Schema 更完善,功能更强大
- XML Schema 基于 XML 编写
- XML Schema 支持数据类型
- XML Schema 支持命名空间
XML Schema 支持数据类型
通过对数据类型的支持:
- 可更容易地描述允许的文档内容
- 可更容易地验证数据的正确性
- 可更容易地与来自数据库的数据一并工作
- 可更容易地定义数据约束(data facets)
- 可更容易地定义数据模型(或称数据格式)
- 可更容易地在不同的数据类型间转换数据
XML Schema 使用 XML 语法
由 XML 编写 XML Schema 好处:
- 不必学习新的语言
- 可使用 XML 编辑器来编辑 Schema 文件
- 可使用 XML 解析器来解析 Schema 文件
- 可通过 XML DOM 来处理 Schema
- 可通过 XSLT 来转换 Schema
XML Schema 可保护数据通信
通过 XML Schema,发送方可以用一种接受方能够明白的方式来描述数据。
带有数据类型的 XML 元素,比如:<date type="date">2004-03-11</date>,可确保对内容一致的理解,这是因为 XML 的数据类型 "date" 要求的格式是 "YYYY-MM-DD"。
XML Schema 可扩展
XML Schema 是可扩展的,因为它们由 XML 编写。
通过可扩展的 Schema 定义:
- 在其他 Schema 中重复使用您的 Schema
- 创建由标准类型衍生而来的您自己的数据类型
- 在相同的文档中引用多重的 Schema
使用 XML Schema
XML 文档可对 DTD 或 XML Schema 进行引用。
XML 文档
名为 "note.xml" 的 XML 文档:
<?xml version="1.0"?>
<note>
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
DTD 文件
名为 "note.dtd" 的 DTD 文件,对上面那个 XML 文档( "note.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.xxx.org/xxxx/XMLSchema"
targetNamespace="http://www.xxxxxx.com"
xmlns="http://www.xxxxxx.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 的引用
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "//www.xxxxxx.cn/dtd/note.dtd">
<note>
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
对 XML Schema 的引用
<?xml version="1.0"?>
<note
xmlns="http://www.xxxxxx.com"
xmlns:xsi="http://www.xxx.org/xxxx/XMLSchema-instance"
xsi:schemaLocation="http://www.xxxxxx.com note.xsd">
<to>y</to>
<from>x</from>
<heading>xxxxxx</heading>
<body>xxxxxxxxxxxx</body>
</note>
XML schema 元素
定义和用法
schema 元素定义 schema 的根元素。
元素信息
- 父元素: (无父元素)
语法
<schema
id=ID
attributeFormDefault=qualified|unqualified
elementFormDefault=qualified|unqualified
blockDefault=(#all|list of (extension|restriction|substitution))
finalDefault=(#all|list of (extension|restriction|list|union))
targetNamespace=anyURI
version=token
xmlns=anyURI
any attributes
>
((include|import|redefine|annotation)*,(((simpleType|complexType|
group|attributeGroup)|element|attribute|notation),annotation*)*)
</schema>
属性 | 描述 |
id | 可选。规定该元素的唯一的 ID。 |
attributeFormDefault | 可选。在该 schema 的目标命名空间中声明的属性的形式。该值必须是下列字符串之一: "qualified" 或 "unqualified"。 默认值为 "unqualified"。
|
elementFormDefault | 可选。在该 schema 的目标命名空间中声明的元素的形式。该值必须是下列字符串之一: "qualified" 或 "unqualified"。 默认值为 "unqualified"。
|
blockDefault | 可选。规定在目标命名空间中 element 和 complexType 元素上的 block 属性的默认值。block 属性防止具有指定派生类型的复杂类型(或元素)被用来代替继承的复杂类型(或元素)。该值可以包含 #all 或者一个列表,该列表是 extension、restriction 或 substitution 的子集:
|
finalDefault | 可选。规定在该架构的目标命名空间中 element、simpleType 和 complexType 元素的 final 属性的默认值。final 属性防止 element、simpleType 或 complexType 元素的指定的派生类型。对于 element 和 complexType 元素,该值可以包含 #all 或一个列表,该列表是 extension 或 restriction 的子集。 对于 simpleType 元素,该值还可以包含 list 和 union:
|
targetNamespace | 该 schema 的命名空间的 URI 引用。还可以分配该命名空间的前缀。如果没有分配任何前缀,则该命名空间的 schema 组件可以和非限定的引用一起使用。 |
version | 可选。规定 schema 的版本。 |
xmlns | 规定在此 schema 中使用的一个或多个命名空间的 URI 引用。如果没有分配前缀,该命名空间的 schema 组件可与未限制的引用使用。 |
any attributes | 可选。规定带有 non-schema 命名空间的任何其他属性。 |
实例
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.xxx.org/xxxx/XMLSchema">
<xs:element name="values" type="xs:string">
</xs:schema>
实例
<?xml version="1.0"?>
<schema xmlns="http://www.xx.org/xxxx/XMLSchema"
xmlns:wsc="//www.xxxxxx.cn/xxxxxx">
<element name="fname" type="wsc:mystring"/> <!--通过 wsc 前缀限制的-->
</schema>
XSD 简易元素
简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性。
文本有很多类型。可以是 XML Schema 定义中包括的类型中的一种(布尔、字符串、数据等等),或者也可以是您自行定义的定制类型。
可向数据类型添加限定(即 facets),以此来限制它的内容,或者您可以要求数据匹配某种特定的模式。
定义简易元素
语法:
<xs:element name="xxx" type="yyy"/>
此处 xxx 指元素的名称,yyy 指元素的数据类型。
最常用的类型是:
- xs:string
- xs:decimal
- xs:integer
- xs:boolean
- xs:date
- xs:time
实例
一些 XML 元素:
<lastname>xxxxxx</lastname>
<age>xx</age>
<dateborn>xxxx-xx-xx</dateborn>
相应的简易元素定义:
<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>
简易元素的默认值和固定值
简易元素可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
下面的例子中,缺省值是 "red":
<xs:element name="color" type="xs:string" default="red"/>
固定值同样会自动分配给元素,并且您无法规定另外一个值。
下面的例子中,固定值是 "red":
<xs:element name="color" type="xs:string" fixed="red"/>
XML Schema 属性
简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
定义属性的语法:
<xs:attribute name="xxx" type="yyy"/>
xxx 指属性名称,yyy 则规定属性的数据类型。
最常用的类型:
- xs:string
- xs:decimal
- xs:integer
- xs:boolean
- xs:date
- xs:time
实例
带有属性的 XML 元素:
<lastname lang="EN">xxxxxx</lastname>
对应的属性定义:
<xs:attribute name="lang" type="xs:string"/>
属性的默认值和固定值
属性可拥有指定的默认值或固定值。
当没有其他的值被规定时,默认值就会自动分配给元素。
在下面的例子中,缺省值是 "EN":
<xs:attribute name="lang" type="xs:string" default="EN"/>
固定值同样会自动分配给元素,并且您无法规定另外的值。
在下面的例子中,固定值是 "EN":
<xs:attribute name="lang" type="xs:string" fixed="EN"/>
可选的和必需的属性
在缺省的情况下,属性是可选的。如需规定属性为必选,请使用 "use" 属性:
<xs:attribute name="lang" type="xs:string" use="required"/>
对内容的限定
当 XML 元素或属性拥有被定义的数据类型时,就会向元素或属性的内容添加限定。
假如 XML 元素的类型是 "xs:date",而其包含的内容是类似 "Hello World" 的字符串,元素将不会(通过)验证。
XML Schema 限定 / Facets
限定用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet。
对值的限定
定义带有一个限定且名为 "age" 的元素。age 的值不能低于 0 或者高于 120:
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
对一组值的限定
如需把 XML 元素的内容限制为一组可接受的值,要使用枚举约束。
定义带有一个限定的名为 "car" 的元素。值只有:x,y,z:
<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="x"/>
<xs:enumeration value="y"/>
<xs:enumeration value="z"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
或
<xs:element name="car" type="carType"/>
<xs:simpleType name="carType">
<xs:restriction base="xs:string">
<xs:enumeration value="x"/>
<xs:enumeration value="y"/>
<xs:enumeration value="z"/>
</xs:restriction>
</xs:simpleType>
注意: 在这种情况下,类型 "carType" 可被其他元素使用,因为它不是 "car" 元素的组成部分。
对一系列值的限定
如需把 XML 元素的内容限制定义为一系列可使用的数字或字母,我们要使用模式约束。
定义带有一个限定的名为 "letter" 的元素。值只有小写字母 a - z 其中的一个:
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "initials" 的元素。值是大写字母 A - Z 其中的三个:
<xs:element name="initials">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z][A-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "initials" 的元素。值是大写或小写字母 a - z 其中的三个:
<xs:element name="initials">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "choice 的元素。值是字母 x, y 或 z 中的一个:
<xs:element name="choice">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[xyz]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "prodid" 的元素。值是五个数字的一个序列,每个数字的范围是 0-9:
<xs:element name="prodid">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
对一系列值的其他限定
定义带有一个限定的名为 "letter" 的元素。值是 a - z 中零个或多个字母:
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="([a-z])*"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "letter" 的元素。值是一对或多对字母,每对字母由一个小写字母后跟一个大写字母组成。
<xs:element name="letter">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="([a-z][A-Z])+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "gender" 的元素。值是 male 或者 female:
<xs:element name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "password" 的元素。值是由 8 个字符组成的一行字符,这些字符必须是大写或小写字母 a - z 亦或数字 0 - 9:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z0-9]{8}"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
对空白字符的限定
如需规定对空白字符的处理方式,需要使用 whiteSpace 限定。
定义带有一个限定的名为 "address" 的元素。这个 whiteSpace 限定被设置为 "preserve",这意味着 XML 处理器不会移除任何空白字符:
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "address" 的元素。这个 whiteSpace 限定被设置为 "replace",这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符):
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="replace"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义带有一个限定的名为 "address" 的元素。这个 whiteSpace 限定被设置为 "collapse",这意味着 XML 处理器将移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多个连续的空格会被缩减为一个单一的空格):
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
对长度的限定
如需限制元素中值的长度,需要使用 length、maxLength 以及 minLength 限定。
定义了带有一个限定且名为 "password" 的元素。其值必须精确到 8 个字符:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义了带有一个限定的名为 "password" 的元素。其值最小为 5 个字符,最大为 8 个字符:
<xs:element name="password">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="5"/>
<xs:maxLength value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
数据类型的限定
限定 | 描述 |
enumeration | 定义可接受值的一个列表 |
fractionDigits | 定义所允许的最大的小数位数。必须大于等于0。 |
length | 定义所允许的字符或者列表项目的精确数目。必须大于或等于0。 |
maxExclusive | 定义数值的上限。所允许的值必须小于此值。 |
maxInclusive | 定义数值的上限。所允许的值必须小于或等于此值。 |
maxLength | 定义所允许的字符或者列表项目的最大数目。必须大于或等于0。 |
minExclusive | 定义数值的下限。所允许的值必需大于此值。 |
minInclusive | 定义数值的下限。所允许的值必需大于或等于此值。 |
minLength | 定义所允许的字符或者列表项目的最小数目。必须大于或等于0。 |
pattern | 定义可接受的字符的精确序列。 |
totalDigits | 定义所允许的阿拉伯数字的精确位数。必须大于0。 |
whiteSpace | 定义空白字符(换行、回车、空格以及制表符)的处理方式。 |
XML Schema 复合元素
复合元素指包含其他元素及/或属性的 XML 元素。
有四种类型的复合元素:
- 空元素
- 包含其他元素的元素
- 仅包含文本的元素
- 包含元素和文本的元素
注意: 上述元素均可包含属性!
例子
复合元素,"product",是空的:
<product x="222"/>
复合元素,"employee",仅包含其他元素:
<employee>
<firstname>x</firstname>
<lastname>y</lastname>
</employee>
复合 XML 元素,"food",仅包含文本:
<food type="dessert">Ice cream</food>
复合XML元素,"description"包含元素和文本:
<description>
xxxxxx<date lang="xx">xx.xx.xx</date> ....
</description>
定义复合元素
这个复合 XML 元素,"employee",仅包含其他元素:
<employee>
<firstname>x</firstname>
<lastname>y</lastname>
</employee>
有两种方式来定义复合元素:
1. 通过命名此元素,可直接对"employee"元素进行声明:
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
使用上面所描述的方法,那么仅有 "employee" 可使用所规定的复合类型。
注意其子元素,"firstname" 以及 "lastname",被包围在指示器 <sequence>中。
这意味着子元素必须以它们被声明的次序出现。
2. "employee" 元素可以使用 type 属性,这个属性的作用是引用要使用的复合类型的名称:
<xs:element name="employee" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
使用了上面所描述的方法,那么若干元素均可以使用相同的复合类型:
<xs:element name="employee" type="personinfo"/>
<xs:element name="student" type="personinfo"/>
<xs:element name="member" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
可以在已有的复合元素之上以某个复合元素为基础,然后添加一些元素:
<xs:element name="employee" type="fullpersoninfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
XML Schema 复合空元素
空的复合元素不能包含内容,只能含有属性。
复合空元素:
一个空的 XML 元素:
<product prodid="0000" />
"product" 元素根本没有内容。
为了定义无内容的类型,我们就必须声明一个在其内容中只能包含元素的类型。
实际上我们并不会声明任何元素:
<xs:element name="product">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="xs:integer">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
在上面的例子中,定义了一个带有复合内容的复合类型。
complexContent 元素给出的信号是,我们打算限定或者拓展某个复合类型的内容模型。
integer 限定则声明了一个属性但不会引入任何的元素内容。
也可以更加紧凑地声明此 "product" 元素:
<xs:element name="product">
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
</xs:element>
或者您可以为一个 complexType 元素起一个名字,然后为 "product" 元素设置一个 type 属性并引用这个 complexType 名称(通过使用此方法,若干个元素均可引用相同的复合类型):
<xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
XML Schema 复合类型 – 仅含元素
复合类型仅包含元素
XML 元素,"person",仅包含其他的元素:
<person>
<firstname>x</firstname>
<lastname>y</lastname>
</person>
在 schema 中定义 "person" 元素:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子定义元素意味着被定义的元素必须按上面的次序出现在 "person" 元素中。
或者可以为 complexType 元素设定一个名称,并让 "person" 元素的 type 属性来引用此名称
(如使用此方法,若干元素均可引用相同的复合类型):
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
XML Schema 复合元素 – 仅含文本
仅含文本的复合元素
此类型仅包含简易的内容(文本和属性),因此我们要向此内容添加 simpleContent 元素。
当使用简易内容时,我们就必须在 simpleContent 元素内定义扩展或限定:
<xs:element name="somename">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="basetype">
....
....
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
或者:
<xs:element name="somename">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="basetype">
....
....
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
提示: 请使用 extension 或 restriction 元素来扩展或限制元素的基本简易类型。
实例
元素"shoesize",其中仅包含文本:
<shoesize country="france">11</shoesize>
下面声明了一个复合类型,其内容被定义为整数值,并且 "shoesize" 元素含有名为 "country" 的属性:
<xs:element name="shoesize">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
也可为 complexType 元素设定一个名称,并让 "shoesize" 元素的 type 属性来引用此名称
(通过使用此方法,若干元素均可引用相同的复合类型):
<xs:element name="shoesize" type="shoetype"/>
<xs:complexType name="shoetype">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
XML Schema 复合类型 – 混合内容
带有混合内容的复合类型
XML 元素,"letter",含有文本以及其他元素:
<letter>
xx<name>xxxxxx</name>.
Your order <orderid>xxxx</orderid>
will be shipped on <shipdate>xxxx-xx-xx</shipdate>.
</letter>
下面这个 schema 声明了这个 "letter" 元素:
<xs:element name="letter">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
</xs:element>
注意: 为了使字符数据可以出现在 "letter" 的子元素之间,mixed 属性必须被设置为 "true"。<xs:sequence> 标签 (name、orderid 以及 shipdate ) 意味着被定义的元素必须依次出现在 "letter" 元素内部。
也可以为 complexType 元素起一个名字,并让 "letter" 元素的 type 属性引用 complexType 的这个名称(通过这个方法,若干元素均可引用同一个复合类型):
<xs:element name="letter" type="lettertype"/>
<xs:complexType name="lettertype" mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
XML Schema 指示器
指示器
七种指示器:
Order 指示器:
- All
- Choice
- Sequence
Occurrence 指示器:
- maxOccurs
- minOccurs
Group 指示器:
- Group name
- attributeGroup name
Order 指示器
All 指示器
<all> 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次:
<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>
注意: 当使用 <all> 指示器时,你可以把 <minOccurs> 设置为 0 或者 1,而只能把 <maxOccurs> 指示器设置为 1
Choice 指示器
<choice> 指示器规定可出现某个子元素或者可出现另外一个子元素:
<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>
Sequence 指示器
<sequence> 规定子元素必须按照特定的顺序出现:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Occurrence 指示器
Occurrence 指示器用于定义某个元素出现的频率。
注意: 对于所有的 "Order" 和 "Group" 指示器(any、all、choice、sequence、group name 、 group reference),其中的 maxOccurs 以及 minOccurs 的默认值均为 1。
maxOccurs 指示器
<maxOccurs> 指示器可规定某个元素可出现的最大次数:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子表明,子元素 "child_name" 可在 "person" 元素中最少出现一次(其中 minOccurs 的默认值是 1),最多出现 10 次。
minOccurs 指示器
<minOccurs> 指示器可规定某个元素能够出现的最小次数:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子表明,子元素 "child_name" 可在 "person" 元素中出现最少 0 次,最多出现 10 次。
提示:如需使某个元素的出现次数不受限制,请使用 maxOccurs="unbounded" 这个声明:
Group 指示器
Group 指示器用于定义相关的数批元素。
元素组
元素组通过 group 声明进行定义:
<xs:group name="groupname">
...
</xs:group>
必须在 group 声明内部定义一个 all、choice 或者 sequence 元素。
下面例子定义了名为 "persongroup" 的 group,定义了必须按照精确的顺序出现的一组元素:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="xxx" type="xs:string"/>
<xs:element name="yyy" type="xs:string"/>
<xs:element name="zzz" type="xs:date"/>
</xs:sequence>
</xs:group>
可以在另一个定义中引用它:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="xxx" type="xs:string"/>
<xs:element name="yyy" type="xs:string"/>
<xs:element name="zzz" type="xs:date"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
属性组
属性组通过 attributeGroup 声明来进行定义:
<xs:attributeGroup name="groupname">
...
</xs:attributeGroup>
下面这个例子定义了名为 "personattrgroup" 的属性组:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="xxx" type="xs:string"/>
<xs:attribute name="yyy" type="xs:string"/>
<xs:attribute name="zzz" type="xs:date"/>
</xs:attributeGroup>
可以在另一个定义中引用它:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="xxx" type="xs:string"/>
<xs:attribute name="yyy" type="xs:string"/>
<xs:attribute name="zzz" type="xs:date"/>
</xs:attributeGroup>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
XML Schema any 元素
<any> 元素使我们有能力通过未被 schema 规定的元素来拓展 XML 文档!
下面这个例子展示了一个针对 "person" 元素的声明。
通过使用 <any> 元素,我们可以通过任何元素(在 <lastname> 之后)扩展 "person" 的内容:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="xxx" type="xs:string"/>
<xs:element name="yyy" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
提示:在一个复杂类型中加入 <xs:any minOccurs="0"/>,则可通过其他外部元素扩展原复杂类型。
使用 "children" 元素来扩展 "person" 元素。这此种情况下我们就可以这么做,即使以上这个 schema 的作者没有声明任何 "children" 元素。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.xx.org/xxxx/XMLSchema"
targetNamespace="http://www.xxxxxx.com"
xmlns="http://www.xxxxxx.com"
elementFormDefault="qualified">
<xs:element name="children">
<xs:complexType>
<xs:sequence>
<xs:element name="childname" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<any> 和 <anyAttribute> 均可用于制作可扩展的文档!它们使文档有能力包含未在主 XML schema 中声明过的附加元素。
XML Schema anyAttribute 元素
<anyAttribute> 元素使我们有能力通过未被 schema 规定的属性来扩展 XML 文档!
下面的例子为我们展示了针对 "person" 元素的一个声明。通过使用 <anyAttribute> 元素,我们就可以向 "person" 元素添加任意数量的属性:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="xxx" type="xs:string"/>
<xs:element name="yyy" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element>
通过 "gender" 属性来扩展 "person" 元素。在这种情况下我们就可以这样做,即使这个 schema 的作者从未声明过任何 "gender" 属性。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.xx.org/xxxx/XMLSchema"
targetNamespace="http://www.xxxxxx.com"
xmlns="http://www.xxxxxx.com"
elementFormDefault="qualified">
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:schema>
XML Schema 元素替换
在 XML Schema,如果想指定某个元素可替代另一个元素,可为该元素增加 substitutionGroup 属性,属性值是该元素想要替换的元素名字。
元素替换
举例:用户来自英国和挪威。让用户选择在 XML 文档中使用挪威语的元素名称还是英语的元素名称。
为了解决这个问题,可以在 XML schema 中定义一个 substitutionGroup。
首先,我们声明主元素,然后我们会声明次元素,这些次元素可声明它们能够替换主元素。
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
在上面的例子中,"name" 元素是主元素,而 "navn" 元素可替代 "name" 元素。
XML schema 的片段:
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>
有效的 XML 文档类似这样:
<customer>
<name>x</name>
</customer>
或类似这样:
<kunde>
<navn>y</navn>
</kunde>
XML Schema 元素替换注意事项:
1、替换元素和被替换元素都必须使用全局元素来声明;
2、替换元素与被替换元素要么有相同的数据类型,要么替换元素类型是被替换元素类型的派生类型。
阻止元素替换
为防止其他的元素替换某个指定的元素,请使用 block 属性:
<xs:element name="name" type="xs:string" block="substitution"/>
XML schema 的片段:
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>
合法的 XML 文档应该类似这样:
<customer>
<name>x</name>
</customer>
但是下面的文档不再合法:
<kunde>
<navn>x</navn>
</kunde>
使用 substitutionGroup
可替换元素的类型必须和主元素相同,或者从主元素衍生而来。假如可替换元素的类型与主元素的类型相同,那么您就不必规定可替换元素的类型了。
请注意,substitutionGroup 中的所有元素(主元素和可替换元素)必须被声明为全局元素,否则就无法工作!
全局元素
全局元素指 "schema" 元素的直接子元素!本地元素指嵌套在其他元素中的元素。
XML Schema 字符串数据类型
字符串数据类型
字符串数据类型可包含字符、换行、回车以及制表符。
注意:如果您使用字符串数据类型,XML 处理器就不会更改其中的值。
规格化字符串数据类型
规格化字符串数据类型源自于字符串数据类型。
规格化字符串数据类型同样可包含字符,但是 XML 处理器会移除折行,回车以及制表符。
注意:在上面的例子中,XML 处理器会使用空格替换所有的制表符。
Token 数据类型
Token 数据类型同样源自于字符串数据类型。
Token 数据类型同样可包含字符,但是 XML 处理器会移除换行符、回车、制表符、开头和结尾的空格以及(连续的)空格。
注意:>在上面这个例子中,XML 解析器会移除制表符。
字符串数据类型
名称 | 描述 |
ENTITIES | |
ENTITY | |
ID | 在 XML 中提交 ID 属性的字符串 (仅与 schema 属性一同使用) |
IDREF | 在 XML 中提交 IDREF 属性的字符串(仅与 schema 属性一同使用) |
IDREFS language | 包含合法的语言 id 的字符串 |
Name | 包含合法 XML 名称的字符串 |
NCName | |
NMTOKEN | 在 XML 中提交 NMTOKEN 属性的字符串 (仅与 schema 属性一同使用) |
NMTOKENS | |
normalizedString | 不包含换行符、回车或制表符的字符串 |
QName | |
string | 字符串 |
token | 不包含换行符、回车或制表符、开头或结尾空格或者多个连续空格的字符串 |
对字符串数据类型的限定
- enumeration
- length
- maxLength
- minLength
- pattern (NMTOKENS、IDREFS 以及 ENTITIES 无法使用此约束)
- whiteSpace
XML Schema 日期/时间 数据类型
日期数据类型
日期数据类型用于定义日期。
日期使用此格式进行定义:"YYYY-MM-DD",其中:
- YYYY 表示年份
- MM 表示月份
- DD 表示天数
注意:所有的成分都是必需的
例子:
<xs:element name="start" type="xs:date"/>
文档中的元素看上去类似这样:
<start>xxxx-xx-xx</start>
时区
如需规定一个时区,您也可以通过在日期后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个日期
<start>xxxx-xx-xxZ</start>
或者也可以通过在日期后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量
<start>xxxx-xx-xx-xx:xx</start>
或者
<start>xxxx-xx-xx+xx:xx</start>
提示:利用 xs:date() 来强制转换某个字符串为日期类型时,字符串参数的格式需要严格按照遵循:yyyy-mm-dd。
h2>时间数据类型
时间数据类型用于定义时间。
时间使用下面的格式来定义:"hh:mm:ss",其中
- hh 表示小时
- mm 表示分钟
- ss 表示秒
注意: 所有的成分都是必需的!
例子:
<xs:element name="start" type="xs:time"/>
文档中的元素看上去类似这样:
<start>xx:xx:xx</start>
或者类似这样:
<start>xx:xx:xx.x</start>
时区
如需规定一个时区,您也可以通过在时间后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个时间
<start>xx:xx:xxZ</start>
或者也可以通过在时间后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量
<start>xx:xx:xx-xx:xx</start>
or
<start>xx:xx:xx+xx:xx</start>
日期时间数据类型
日期时间数据类型用于定义日期和时间。
日期时间使用下面的格式进行定义:"YYYY-MM-DDThh:mm:ss",其中:
- YYYY 表示年份
- MM 表示月份
- DD 表示日
- T 表示必需的时间部分的起始
- hh 表示小时
- mm 表示分钟
- ss 表示秒
注意: 所有的成分都是必需的!
例子:
<xs:element name="startdate" type="xs:dateTime"/>
文档中的元素看上去类似这样:
<startdate>xxxx-xx-xxTxx:xx:xx</startdate>
或者类似这样:
<startdate>xxxx-xx-xxTxx:xx:xx.x</startdate>
时区
如需规定一个时区,您也可以通过在日期时间后加一个 "Z" 的方式,使用世界调整时间(UTC time)来输入一个日期时间
<startdate>xxxx-xx-xxTxx:xx:xxZ</startdate>
或者也可以通过在时间后添加一个正的或负时间的方法,来规定以世界调整时间为准的偏移量
<startdate>xxxx-xx-xxTxx:xx:xx-xx:xx</startdate>
或者
<startdate>xxxx-xx-xxTxx:xx:xx+xx:xx</startdate>
h2>持续时间数据类型
持续时间数据类型用于规定时间间隔。
时间间隔使用下面的格式来规定:"PnYnMnDTnHnMnS",其中:
- P 表示周期(必需)
- nY 表示年数
- nM 表示月数
- nD 表示天数
- T 表示时间部分的起始 (如果您打算规定小时、分钟和秒,则此选项为必需)
- nH 表示小时数
- nM 表示分钟数
- nS 表示秒数
例子:
<xs:element name="period" type="xs:duration"/>
文档中的元素看上去类似这样:
<period>P5Y</period>
表示一个 5 年的周期。
或者
<period>P5Y2M10D</period>
表示一个 5 年、2 个月及 10 天的周期。
或者
<period>P5Y2M10DT15H</period>
表示一个 5 年、2 个月、10 天及 15 小时的周期。
或者
<period>PT15H</period>
表示一个 15 小时的周期。
负的持续时间
如需规定一个负的持续时间,请在 P 之前输入减号:
<period>-P10D</period>
表示一个负 10 天的周期。
日期和时间数据类型
名称 | 描述 |
date | 定义一个日期值 |
dateTime | 定义一个日期和时间值 |
duration | 定义一个时间间隔 |
gDay | 定义日期的一个部分 - 天 (DD) |
gMonth | 定义日期的一个部分 - 月 (MM) |
gMonthDay | 定义日期的一个部分 - 月和天 (MM-DD) |
gYear | 定义日期的一个部分 - 年 (YYYY) |
gYearMonth | 定义日期的一个部分 - 年和月 (YYYY-MM) |
time | 定义一个时间值 |
对日期数据类型的限定
- enumeration
- maxExclusive
- maxInclusive
- minExclusive
- minInclusive
- pattern
- whiteSpace
XML Schema 数值数据类型
十进制数据类型
例子
<xs:element name="prize" type="xs:decimal"/>
文档中的元素看上去类似这样:
<prize>999.50</prize>
<prize>+999.5450</prize>
<prize>-999.5230</prize>
<prize>0</prize>
<prize>14</prize>
整数数据类型
整数数据类型用于规定无小数成分的数值。
例子
<xs:element name="prize" type="xs:integer"/>
文档中的元素看上去类似这样:
<prize>999</prize>
<prize>+999</prize>
<prize>-999</prize>
<prize>0</prize>
数值数据类型
名字 | 秒数 |
byte | 有正负的 8 位整数 |
decimal | 十进制数 |
int | 有正负的 32 位整数 |
integer | 整数值 |
long | 有正负的 64 位整数 |
negativeInteger | 仅包含负值的整数 ( .., -2, -1.) |
nonNegativeInteger | 仅包含非负值的整数 (0, 1, 2, ..) |
nonPositiveInteger | 仅包含非正值的整数 (.., -2, -1, 0) |
positiveInteger | 仅包含正值的整数 (1, 2, ..) |
short | 有正负的 16 位整数 |
unsignedLong | 无正负的 64 位整数 |
unsignedInt | 无正负的 32 位整数 |
unsignedShort | 无正负的 16 位整数 |
unsignedByte | 无正负的 8 位整数 |
对数值数据类型的限定
- enumeration
- fractionDigits
- maxExclusive
- maxInclusive
- minExclusive
- minInclusive
- pattern
- totalDigits
- whiteSpace
XML Schema 杂项数据类型
布尔数据类型
布尔数据性用于规定 true 或 false 值。
例子:
<xs:attribute name="disabled" type="xs:boolean"/>
文档中的元素看上去类似这样:
<prize disabled="true">999</prize>
注意: 合法的布尔值是 true、false、1(表示 true) 以及 0(表示 false)。
二进制数据类型
二进制数据类型用于表达二进制形式的数据。
我们可使用两种二进制数据类型:
- base64Binary (Base64 编码的二进制数据)
- hexBinary (十六进制编码的二进制数据)
例子:
<xs:element name="blobsrc" type="xs:hexBinary"/>
AnyURI 数据类型
anyURI 数据类型用于规定 URI。
例子:
<xs:attribute name="src" type="xs:anyURI"/>
文档中的元素看上去类似这样:
<pic src="//www.xxxxxx.cn/images/smiley.gif" />
注意: 如果某个 URI 含有空格,请用 %20 替换它们。
杂项数据类型
名称 | 描述 |
anyURI | |
base64Binary | |
boolean | |
double | |
float | |
hexBinary | |
NOTATION | |
QName |
对杂项数据类型的限定
- enumeration (布尔数据类型无法使用此约束*)
- length (布尔数据类型无法使用此约束)
- maxLength (布尔数据类型无法使用此约束)
- minLength (布尔数据类型无法使用此约束)
- pattern
- whiteSpace