1 of 47
1
«
‹
›
»
47
A+
A-
1. 首页 2. 目录 3. XML 4. 格式规范并且合法的 XML (Well-Formed and Valid XML) 5. 格式规范的 XML(Well-Formed XML) 6. 标签(Tags) 7. 例子: 格式规范的 XML 8. DTD 的结构 9. DTD 中的元素 10. 例子: DTD 11. 元素的描述 12. 例子: 元素的描述 13. DTD 的使用 14. 例子: (1) 15. 例子: (2) 16. 属性(Attributes) 17. 例子: 属性(Attributes) 18. 例子: 属性的使用 19. 标识符和引用(ID's and IDREF's) 20. 创建标识符(ID) 21. 创建引用(IDREF) 22. 例子: ID's and IDREF's 23. The DTD 24. 例子: A Document 25. 空元素(Empty Elements) 26. 例子: 空元素(Empty Elements) 27. XML 模式 28. XML-模式文档的结构 29. <j>xs:element</j> 元素 30. 例子: <j>xs:element</j> 31. 复杂类型(Complex Types) 32. 例子: a Type for Beers 33. 属于 <j>beerType</j> 类型的一个元素 34. 例子: a Type for Bars 35. <j>xs:attribute</j> 36. 例子: <j>xs:attribute</j> 37. 属于上面新定义类型 <j>beerType</j> 的一个元素 38. 受限的简单类型 39. Restrictions 40. 例子: 关于酒吧 license 的简单枚举类型 41. 例子: 价格限制在 <mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="0" style="font-size: 127.3%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mo class="mjx-n"><mjx-c class="mjx-c5B"></mjx-c></mjx-mo><mjx-mn class="mjx-n"><mjx-c class="mjx-c31"></mjx-c></mjx-mn><mjx-mo class="mjx-n"><mjx-c class="mjx-c2C"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="2"><mjx-c class="mjx-c35"></mjx-c></mjx-mn><mjx-mo class="mjx-n"><mjx-c class="mjx-c29"></mjx-c></mjx-mo></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mo stretchy="false">[</mo><mn>1</mn><mo>,</mo><mn>5</mn><mo stretchy="false">)</mo></math></mjx-assistive-mml></mjx-container> 区间 42. XML 模式中的键 43. 例子: 键 44. 外键 45. 例子: 外键 46. 例子: XML 模式中的外键 47. End
½
数据库理论 ATZJG.NET Haifeng Xu
首页
Document Type Definitions
XML Schema
Haifeng Xu
(hfxu@yzu.edu.cn)
This slide is based on Jeffrey D. Ullman's work, which can be download from his website.
格式规范并且合法的 XML (Well-Formed and Valid XML)
格式规范并且合法的 XML
XML 可以应用于两种不同的模式:
格式规范的 XML(Well-Formed XML) , 或“结构良好”的XML文档, 指语法正确的 XML. (允许用户自定义标签等等.)
合法的 XML(Valid XML) , 包括一个 DTD , 即文档类型定义(Document Type Definition). 它指定了允许使用的标签并给出了如何嵌套它们的语法. 通过 DTD 验证的 XML 是“合法”的XML.
格式规范的 XML
XML 文档必须有根元素
XML 文档必须有关闭标签
XML 标签对大小写敏感
XML 元素必须被正确嵌套
XML 属性必须加引号
参考资料
XML 验证器
http://www.runoob.com/xml/xml-validator.html
格式规范的 XML(Well-Formed XML)
格式规范的 XML(Well-Formed XML)
以一个 XML 声明开始, 形如 <?xml ... ?>
声明为:
<?xml version = "1.0" standalone = "yes" ?>
<?xml version = "1.0" encoding="ISO-8859-1" ?>
version="1.0" 表示 XML 的版本 (1.0)
encoding="ISO-8859-1" 表示使用ISO-8859-1编码 (ISO-8859-1 = Latin-1/西欧字符集)。
standalone="yes" 说明本文档没有 DTD.
XML 的声明不需要闭标签. 其余XML的元素均需要闭标签.
文档需要有一个根元素(root element) , 或根标签(root tag) . 它围住了里面的嵌套标签.
标签(Tags)
标签(Tags)
标签通常是成对出现的, 如 <FOO> ... </FOO>
也允许单标签, 如 <FOO/>
标签可以随意嵌套.
XML 标签是大小写敏感的.
例子: 格式规范的 XML
例子: 格式规范的 XML
<?xml version = "1.0" standalone = "yes" ?>
<BARS>
<BAR>
<NAME>Joe's Bar</NAME>
<BEER>
<NAME>Bud</NAME>
<PRICE>2.50</PRICE>
</BEER>
<BEER>
<NAME>Miller</NAME>
<PRICE>3.00</PRICE>
</BEER>
</BAR>
<BAR>
...
</BAR>
</BARS>
这里 <BARS></BARS> 是根标签.
由 <BAR></BAR> 界定了 NAME 子元素和 两个 BEER 元素.
DTD 的结构
DTD 的结构
<!DOCTYPE <root tag> [
<!ELEMENT <name> (<componets>)>
... more elements ...
]>
DTD 中的元素
DTD 中的元素
元素的描述由它的标签名称和由圆括号括起来的任意嵌套子标签的描述组成.
叶子(文本元素) 有 #PCDATA (Parsed Character DATA) 指明.
PCDATA 与 CDATA 的区别
XML 中的CDATA区(CDATA section)允许对XML处理器隐藏类似 < 和 & 的字符. 这是因为这些字符具有特殊的意义:
<是元素的起始标记;
&标志着字符引用或实体引用的开始.
一个CDATA区以字符 <![CDATA[ 开始, 以 ]]> 结束. 例如:
<company><![CDATA[Fitzgerald & Daughters]]></company>
References
http://www.w3.org/TR/REC-xml/#sec-cdata-sect
Michael Fitzgerald, XML HACKS. 靳京、徐亚莉著. P17.
例子: DTD
例子: DTD
<!DOCTYPE BARS [
<!ELEMENT BARS (BAR*)>
<!ELEMENT BAR (NAME, BEER+)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT BEER (NAME,PRICE)>
<!ELEMENT PRICE (#PCDATA)>
]>
首先声明了一个 BARS 对象, 它具有零个或多个 BAR 嵌套标签.
BAR 具有一个 NAME 子元素和一个或多个 BEER 子元素.
BEER 具有一个 NAME 子元素和一个 PRICE 子元素.
NAME 和 PRICE 是文本.
元素的描述
元素的描述
子标签必须依次出现.
标签名后面可以跟一个符号, 以表示它是否可以重复出现, 次数是多少.
* : 零次或多次.
+ : 一次或多次.
? : 零次或一次
符号 | 表示“或者”的意思, 即用它可以组成一个选项列表, 但仅有一个选项可以选择.
例子: 元素的描述
例子: 元素的描述
通常(西方)人名前面可以有一个头衔(比如: "Prof."), 然后是 first name, last name.
现在假设要表示这样一个元素 NAME , 但除了可以表示上面所述的人名外, 它或者可以是一个 IP 地址.
<!ELEMENT NAME (
(TITLE?, FIRST, LAST) | IPADDR
)>
DTD 的使用
DTD 的使用
在一开始的声明中令 standalone="no" , 表示使用了 DTD.
使用下面的任一种方法:
在文档之前包含 DTD, 即在 XML 文档的引言(preamble) 中包含 DTD.
在开始行引用 DTD. DTD 必须在文件系统中分开存放, 处理文档的应用程序应当可以访问到该 DTD. 如:
<!DOCTYPE <root tag> SYSTEM "path/to/file.dtd">
例子: (1)
例子: (1)
<?xml version = "1.0" standalone = "no" ?>
<!-- *** The DTD *** -->
<!DOCTYPE BARS [
<!ELEMENT BARS (BAR*)>
<!ELEMENT BAR (NAME, BEER+)>
<!ELEMENT NAME (#PCDATA)>
<!ELEMENT BEER (NAME, PRICE)>
<!ELEMENT PRICE (#PCDATA)>
]>
<!-- *** The document *** -->
<BARS>
<BAR>
<NAME>Joe's Bar</NAME>
<BEER>
<NAME>Bud</NAME>
<PRICE>2.50</PRICE>
</BEER>
<BEER>
<NAME>Miller</NAME>
<PRICE>3.00</PRICE>
</BEER>
</BAR>
<BAR> ...
</BAR>
</BARS>
例子: (2)
例子: (2)
假设 BARS DTD 存放在文件 bar.dtd 中.
<?xml version = "1.0" standalone = "no" ?>
<!DOCTYPE BARS SYSTEM "bar.dtd">
<BARS>
<BAR>
<NAME>Joe’s Bar</NAME>
<BEER>
<NAME>Bud</NAME>
<PRICE>2.50</PRICE>
</BEER>
<BEER>
<NAME>Miller</NAME>
<PRICE>3.00</PRICE>
</BEER>
</BAR>
<BAR> ...
</BAR>
</BARS>
第二行 <!DOCTYPE BARS SYSTEM "bar.dtd"> 从文件 bar.dtd 中取得 DTD.
属性(Attributes)
属性(Attributes)
XML 中的开始标签可以包含属性(attributes) .
在 DTD 中,
<!ATTLIST E ... >
声明了元素 E 的属性, 后面是它的数据类型.
例子: 属性(Attributes)
例子: 属性(Attributes)
BAR 元素具有一个名为 kind 的属性, 是一个字符串, 用以描述这个酒吧.
<!ELEMENT BAR (NAME BEER*)>
<!ATTLIST BAR kind CDATA #IMPLIED>
CDATA : Character string type; no tags.
#IMPLIED : 表明该属性是可选的. 如果是 #REQUIRED , 则必须要有的.
例子: 属性的使用
例子: 属性的使用
在一个允许使用 BAR 标签的文档中, 我们可能会看到下面的内容:
<BAR kind = "sushi">
<NAME>Homma's</NAME>
<BEER>
<NAME>Sapporo</NAME>
<PRICE>5.00</PRICE>
</BEER>
...
</BAR>
标识符和引用(ID's and IDREF's)
标识符和引用(ID's and IDREF's)
属性可以作为一个对象到另一个对象的指针.
比较 HTML 中的 NAME="foo" 和 HREF="#foo" .
允许 XML 文档成为一个普通的图(graph), 而不只是一个树(tree).
创建标识符(ID)
创建标识符(ID)
给定元素 E 及其类型为 ID 的属性 A .
当在 XML 文档中使用标签 <E> 时, 对其属性 A 指定唯一的值.
如:
<E A = "xyz">
创建引用(IDREF)
创建引用(IDREF)
为使元素 F 指向另一个具有 ID 属性的元素, 我们给定 F 一个类型为 IDREF 的属性.
或者, 令属性具有 IDREFS 类型, 从而 F 元素可以引用任意多个其他元素.
例子: ID's and IDREF's
例子: ID's and IDREF's
新的 BARS DTD 同时包含了 BAR 和 BEER 子元素.
BAR 和 BEER 具有 ID 属性 name .
BAR 具有 SELLS 子元素, 它由一个数(某啤酒的价格)和指向该啤酒的 IDREF 属性 theBeer 组成.
BEER 具有属性 soldBy , 它是指向所有销售该啤酒的酒吧的一个 IDREFS.
The DTD
The DTD
<!DOCTYPE BARS [
<!ELEMENT BARS (BAR*, BEER*)>
<!ELEMENT BAR (SELLS+)>
<!ATTLIST BAR name ID #REQUIRED>
<!ELEMENT SELLS (#PCDATA)>
<!ATTLIST SELLS theBeer IDREF #REQUIRED>
<!ELEMENT BEER EMPTY>
<!ATTLIST BEER name ID #REQUIRED>
<!ATTLIST BEER soldBy IDREFS #IMPLIED>
]>
第二行声明根标签 BARS 范围内可以有零个或多个 BAR 及 BEER 子标签.
第三行声明 BAR 元素具有一个或多个 SELLS 元素.
第四行声明 BAR 元素具有一个名为 name 的标识符(ID), 并且是必须的.
SELLS 元素具有一个值(价格), 以及指向啤酒的一个 IDREF 类型的属性 theBeer .
EMPTY 后面介绍.
BEER 元素具有一个名为 name 的标识符, 必须出现. 还有一个名为 soldBy 的类型为 IDREFS 的可选引用属性. 它的值是用空格隔开的一系列酒吧的名称.
例子: A Document
例子: A Document
<BARS>
<BAR name = "JoesBar">
<SELLS theBeer = "Bud">2.50</SELLS>
<SELLS theBeer = "Miller">3.00</SELLS>
</BAR> ...
<BEER name = "Bud" soldBy = "JoesBar
SuesBar ..." /> ...
</BARS>
空元素(Empty Elements)
空元素(Empty Elements)
我们可以在元素的属性内部完成所有的工作.
另一个例子: SELLS 元素可以具有名为 price 的属性, 而不是用SELLS 的值来表示价格.
例子: 空元素(Empty Elements)
例子: 空元素(Empty Elements)
在 DTD 中, 声明:
<!ELEMENT SELLS EMPTY>
<!ATTLIST SELLS theBeer IDREF #REQUIRED>
<!ATTLIST SELLS price CDATA #REQUIRED>
文档中的 SELLS 标签如下, 注意空元素标签闭合的写法.
<SELLS theBeer = "Bud" price = "2.50" />
XML 模式
XML 模式
XML 模式是描述 XML 文档结构的另一种方式, 比 DTD 更为强大.
XML 模式的模式声明本身是一个 XML 文档.
这些声明描述其中的“元素”, 而那些用来描述的也是“元素”.
XML-模式文档的结构
XML-模式文档的结构
<? xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs =
"http://www.w3.org/2001/XMLschema">
...
</xs:schema>
定义 xs 为如上 URL 所示的命名空间. 这里 xs 可以是任意其他字符串.
在模式元素<xs:schema ...> , </xs:schema> 之间使用 xs 指的就是来自于该命名空间中的标签.
xs:element 元素
xs:element 元素
xs:element 具有下面两个属性.
name : 所定义的元素标签名
type : 元素的类型.
可以是一个 XML-Schema 类型, 如: xs:string .
或者是在文档自身中定义的类型名.
Q: XML Schema 中如何声明空标签?
例子: xs:element
例子: xs:element
<xs:element name="NAME" type="xs:string" />
如: <NAME>Joe's Bar</NAME>
复杂类型(Complex Types)
复杂类型(Complex Types)
为描述包含子元素的元素, 我们使用 xs:complexType .
用于描述该元素的复杂类型的类型名可用属性 name= type name 给出.
一个复杂类型的典型子元素是 xs:sequence , 它本身包含了一列用 xs:element 描述的子元素.
对于 xs:element , 用它的属性 minOccurs 和 maxOccurs 来控制该子元素可以出现的最小次数和最大次数.
复杂类型中的子元素本身也可以是一个复杂类型.
例子: a Type for Beers
例子: a Type for Beers
<xs:complexType name = "beerType">
<xs:sequence>
<xs:element name = "NAME" type = "xs:string"
minOccurs = "1" maxOccurs = "1" />
<xs:element name = "PRICE" type = "xs:float"
minOccurs = "0" maxOccurs = "1" />
</xs:sequence>
</xs:complexType>
名为 <NAME> 的元素只出现一次.
名为 <PRICE> 的元素可以不出现或者出现仅一次, 这与 DTD 中的 ? 类似.
参考
http://www.w3school.com.cn/schema/schema_complex_indicators.asp
属于 beerType 类型的一个元素
属于 beerType 类型的一个元素
<xxx>
<NAME>Bud</NAME>
<PRICE>2.50</PRICE>
</xxx>
这里我们不知道属于此类型(beerType ) 的元素名称是什么.
定义某个子元素应用了某个复杂类型
如果需要声明某个子元素从属于某个复杂类型, 则应在XML Schema中如下写明:
<xs:element name = "Movies">
<xs:complexType>
<xs:sequence>
<xs:element name="Movie" type="movieType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
详见书上P.306 图11-19的例子.
例子: a Type for Bars
例子: a Type for Bars
<xs:complexType name="barType">
<xs:sequence>
<xs:element name="NAME"
type="xs:string"
minOccurs="1" maxOccurs="1" />
<xs:element name="BEER"
type="beerType"
minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
子元素 <BEER> 可以出现零到无穷次, 这与 DTD 中的 * 类似.
xs:attribute
xs:attribute
元素 xs:attribute 可以用在复杂类型中, 用以指出属于该类型的元素的属性.
xs:attribute 的属性:
与 xs:element 中一样, 有 name 和 type .
use="required" 或 "optional" .
例子: xs:attribute
例子: xs:attribute
<xs:complexType name = "beerType">
<xs:attribute name = "name"
type = "xs:string"
use = "required" />
<xs:attribute name = "price"
type = "xs:float"
use = "optional" />
</xs:complexType>
属于上面新定义类型 beerType 的一个元素
属于上面新定义类型 beerType 的一个元素
<xxx name="Bud" price="2.50" />
我们仍然不知道该元素的名称.
并且, 该元素是空的, 因为并没有声明它有子元素.
受限的简单类型
受限的简单类型
xs:simpleType 可以描述枚举类型和数字范围受限类型这两种基本类型.
name 属性的值即为该简单类型的类型名.
xs:restriction 是子元素.
Restrictions
Restrictions
受限的简单类型中元素 restriction 中的描述限制的属性有:
base 属性: 给出这个简单类型是哪一种基础类型, 如: xs:integer .
xs:minInclusive , xs:maxInclusive 表明数字取值的上下界, 包括边界. 如果是 xs:minExclusive , xs:maxExclusive 则恰好相反, 声明的范围在此上下界之外, 且不包含边界.
xs:enumeration 是子元素, 它的属性 value 提供枚举值.
例子: 关于酒吧 license 的简单枚举类型
下面是名为 license 的简单枚举类型
<xs:simpleType name = "license">
<xs:restriction base = "xs:string">
<xs:enumeration value = "Full" />
<xs:enumeration value = "Beer only" />
<xs:enumeration value = "Sushi" />
</xs:restriction>
</xs:simpleType>
例子: 价格限制在 区间
例子: 价格限制在 区间
<xs:simpleType name = "price">
<xs:restriction base = "xs:float"
minInclusive = "1.00"
maxExclusive = "5.00" />
</xs:simpleType>
XML 模式中的键
XML 模式中的键
一个 xs:element 元素可以有一个 xs:key 子元素.
含义 : 在这个元素内, 被某个选择器(selector) 路径到达的所有子元素在某些域的组合上取值唯一.
例子 : 在一个 BAR 元素内, BEER 子元素的 name 属性是唯一的.
例子: 键
例子: 键
<xs:element name = "BAR" ... >
. . .
<xs:key name = "barKey">
<xs:selector xpath = "BEER" />
<xs:field xpath = "@name" />
</xs:key>
. . .
</xs:element>
xpath 是关于 XML 的一种查询语言. 我们这里需要知道的是路径是由 / 隔开的一列标签.
@ 表示这是一个属性而不是标签(子元素).
外键
外键
在元素 xs:element 中的子元素 xs:keyref 指出在这个元素中, 某些(由选择器selector 和域field 定义的)值, 必作为值出现在某个键中.
例子: 外键
例子: 外键
假设我们已经定义元素 BAR 中的子元素 NAME 是关于 BARS 的键.
我们希望声明 DRINKER 元素具有子元素 FREQ . FREQ 的一个属性 bar 是一个指向 BAR 子元素 NAME 的外键.
例子: XML 模式中的外键
例子: XML 模式中的外键
<xs:element name = "DRINKERS">
. . .
<xs:keyref name = "barRef"
refers = "barKey"
<xs:selector xpath = "DRINKER/FREQ" />
<xs:field xpath = "@bar" />
</xs:keyref>
</xs:element>
End
Thanks very much!
This slide is based on Jeffrey D. Ullman's work, which can be download from his website.