首页 > 代码库 > XML
XML
XML概述
标记语言:用一系列约定好的标记来对电子文档进行标记,从而为电子文档额外增加语义、结构和格式等各种方面的信息。
标记语言专为信息增加额外标记,也就是增加一些特殊标志。
XML全称可扩展标记性语言,允许开发者自由定义标签,可以将标签和内容有效分离。
XML更多关注数据如何存储和运输,逐渐演变成跨平台数据交换格式,而不是显示数据。
XML是可扩展标记性语言,没有预定义任何标签,开发者可以自定定义任意的标签。
XML文件只是静态的文本文件,它可以对外提供一些信息,但不能完成任何“动态行为”。程序员必须自行编写软件或程序,才能传送、接收和显示这个文档。
XML文件要满足如下格式:
1、整个XML文件有且仅有一个根元素;
2、每个元素都由开始标签和结束标签组成,除非使用空元素(<adc />);
3、元素与元素之间应该合理嵌套;
4、元素的属性必须有属性值,而且属性值应该用引号引起来(单引双引都可以)。
XML文档可以准确地转换成树状结构,因此XML文档也被称为结构化文档。
XML是与平台无关的数据交换语言。
XML是以纯文本格式对数据进行存储。
通过XML文档,开发人员可以在不兼容的系统之间数据交换,从而解决不兼容系统数据交换的问题。
XML文档规则
XML文档分为:
1、格式不好的XML文档:
完全没有遵守XML文档基本规则的XML文档
2、格式良好但无效的XML文档:
遵守XML文档基本规则,但没有使用DTD或Schema定义语义约束的XML文档。或者使用了DTD或Schema定义了语义约束,但没有遵守所定义的语义约束的XML文档。
3、有效的XML文档:
有效的XML文档除了要满足XML文档的基本规则外,还需要为其提供对其语义约束的DTA或Schema,而且该XML文档必须遵守相应的DTD或Schema所定义的语义约束。
有效的XML文档:
<?xml version="1.0" encoding="GB2312"?> <!DOCTYPE 书籍列表 [ <!ELEMENT 书籍列表 ((计算机书籍+))> <!ELEMENT 计算机书籍 ((书名, 作者, 价格, 简要介绍))> <!ELEMENT 书名 (#PCDATA)> <!ELEMENT 作者 (#PCDATA)> <!ELEMENT 价格 (#PCDATA)> <!ELEMENT 简要介绍 (#PCDATA)> ]> <书籍列表> <计算机书籍> <书名>...</书名> <作者>...</作者> <价格>...</价格> <简要介绍>...</简要介绍> </计算机书籍> </书籍列表>
XML文档的整体结构:
1、有且仅有一个根元素:
两个重要概念:标签和元素
标签:标签是一个由小于号、标志名和大于号组成的字符单元,分为开始标签和结束标签,结束标签比开始标签多了一条斜线。
元素:元素则是通常由开始标签、元素内容和结束标签组成的 <a>...</a>就是一个元素
2、元素必须合理结束:
XML的语法严格区分大小写
3、元素之间必须合理嵌套
4、元素的属性必须有值:
XML文档允许为XML元素指定属性,属性可以为XML元素提供更多的额外信息:
<book desc="第一本书">书</book>
通过使用属性可以简化原本复杂、臃肿的文档
将子元素改写为属性有一个前提条件:子元素包含的内容完全是字符串才可以。
XML文档元素的属性没有顺序要求,每个属性放在前面一点或后面一点没有关系。也就是同一个元素属性是无序的,同一元素不可包含多个同名的属性。
XML元素内包含的子元素是有序的,同一个元素可以包含多个同名的子元素。
XML声明
需要为XML文档使用声明,声明必须放在XML文档第一行。
第一行XML声明告诉XML处理程序,下面的内容遵循该标准。
XML文档声明以"<?"开始,以"?>"结束。
如果指定了XML文档声明,则必须同时指定声明version属性,该属性通常为1.0,表明该文档遵守XML 1.0规范。
XML文档包括两个可选属性:
1、encoiing:指定对该XML文档进行解码所用的字符集,如果没有指定默认UTF-8,如果全是西欧字母就不需要指定任何字符集。
2、standalone:指定该文档是否引用其他资源。该属性只接受yes或no两个值。
XML元素的基本规则
元素是XML文档的基本单元
XML文档没有预置任何元素,XML允许开发者自己扩展元素。
XML元素由开始标签和结束标签组成,结束标签比开始标签多一条斜线。XML文档严格区分大小写。
XML允许无限深度嵌套子元素,只要保证元素之间合理嵌套即可,而且XML元素可以嵌套多个重名的子元素。
XML允许使用空元素语法,空元素不可接受子元素,也不可接受字符串内容。注:空元素和内容为空不同。
<book></book> :空元素
<book> </book> :内容为空元素,开始标签和结束标签之间有空格。
字符数据
开始标签和结束标签之间的文本可以使任何Unicode字符,并且其间的任何字符都将忠实地传递给XML处理程序。
HTML会把多个连续的空格字符裁剪为一个,但XML会保留所有空白。
如果文本中出现一些特殊的符号,比如"<"或者"&"等,由于这些符号在XML中有特殊含义,因此直接在XML元素中使用该字符串会引起混乱。有两种方法解决这个问题:
1、使用实体引用:用另一个特殊标记来代替这些特殊符号。
2、使用CDATA标记:将整段文档定义成字符串:<!CDATA[文本内容]>
注释
<!-- 注释字符串 -->
处理指令
XML处理指令格式:<?处理指令名 处理指令信息?>
XML声明是一种特殊的用法,并非处理指令。
开发者可以定义任意的处理指令,但如果想让指令生效,就必须有合适的程序来解析该指令,并根据该指令进行处理。
W3C对于属性使用建议
1、XML元素的属性必须有属性值,属性值必须用引号引起来;
2、同一个XML元素里不能有多个同名属性;
3、XML元素里的多个属性直接没有先后顺序。
DTD详解
XML语义约束
语义约束可以规定XML文档中允许出现哪些元素。
DTD(文档类型定义),DTD约束主要包括如下几个方面:
1、定义XML文档的根元素、内容和结构;
2、定义XML文档里可以接受哪些元素;
3、定义XML文档里每个元素能接受的合法内容:包括是否为空,是否可包含文本,可接受哪些子元素,子元素之间的顺序和子元素出现的次数等;
4、定义XML文档中每个元素能接受哪些属性;
5、定义XML文档里每个属性的类型,能接受哪些值,以及元素对属性的约束等;
6、定义属性的默认值和固定值;
7、定义XML文档或DTD中可使用的实体。
归纳起来就是:
1、通过使用DTD,可以让每个XML文件自带一个有关其自身格式的描述;
2、不同公司、组织可一致地使用某个标准的DTD来交换数据;
3、应用程序也可使用某个标准的DTD验证所介绍的XML文档是否符合语义约束;
4、开发者自己也可以使用DTD验证所创建的XML文档。
引入DTD
使用DTD定义了合法的语义约束后,必须让XML文档引入该语义约束,以表明该XML文档遵守哪些语义约束。
XML文档引入DTD主要有三种方式:
一、内部DTD
内部DTD是指将DTD与XML数据定义放在同一份文档中,即将DTD定义在XML文档内部。
内部DTD紧跟XML声明和处理指令之后,以<?DOCTYPE开始,以"]"结束。
<? xml version="1.0" encoding=‘GBK‘ standalone="yes" ?> <!DOCTYPE 根元素名[ 元素描述 ]> XML文档主体部分
在内部DTD部分,可采用标准DTD语法详细定义XML文档的语义约束
二、外部DTD
外部DTD的好处是可以方便地被多个XML文档共享,只需定义一份DTD文档,即可为多个XML文档定义语义约束。外部DTD的引用以<!DOCTYPE开始,以>结束
在实际引用中,用于某种数据交换的XML文档,总是具有相同的语义要求,此时采用外部DTD就可以简化语义约束定义。
这样简化有个更大的好处:当语义约束需要改变时,无须为每份文档分别改变DTD定义,只需改变它们共享的外部DTD即可。
<!-- 引用外部DTD --> <!DOCTYPE 根元素名 SYSTEM "外部DTD的URI" >
上面的URI除了使用绝对路径,也可使用相对路径
三、公用DTD
有一种DTD,由某个权威机构指定,供特定行业或公众使用,这种DTD称为公用DTD。公用DTD通过PUBLIC关键字引入:
<!DOCTYPE 根元素 PUBLIC "DTD的标志名" "公用DTD的URI" >
公用DTD和外部DTD的区别在于:公用DTD使用PUBLIC代替了原来的SYSTEM,并增加了DTD标识名。
DTD文档的结构
DTD文档并不是XML文档,而只是为XML定义语义约束的文档,因此DTD文档的语法非常简单。
1、第一行是DTD声明部分,该声明与XML声明的语法相同;
2、0到多个注释部分,DTD注释与XML注释完全相同;
3、0到多个<!ELEMENT...>定义,每个<!ELEMENT..>定义一个XML元素;
4、0到多个<!ATTLIST...>定义,每个<!ATTLIST...>定义一个XML属性;
5、0到多个<!ENTITY...>定义,每个<!ENTITY...>定义一个实体
6、0到多个<!NOTATION...>定义,每个<!NOTATION...>定义一个符号
上面四种定义完全独立,无须相互嵌套。
验证XML文档的有效性
为了验证XML文档是否有效,通常采用如下两种方式:
1、利用专业的XML编辑器进行验证。
2、利用专门的XML解析器进行验证
定义元素
元素类型定义,简称ETD。
ETD不但会定义每个文件中可能存在的元素,给出的元素的名字,而且会定义元素的具体类型。
XML元素可以为空,可以为文本字符串,可以包含若干个子元素,每个子元素又可包含若干子元素。
DTD正是通过元素之间的父子关系,描述了整个文件的结构。
<!-- ETD语法 --><!ELEMENT 元素名 元素类型描述>
元素类型描述主要有如下5种:
1、任意类型:这种元素既可以是字符串,也可以包含其他子元素,还可以是空元素;
<!ELEMENT 元素名 ANY>
<?xml="1.0" encoding="GB2312" standalone="yes"?><!DOCTYPE 书籍列表[ <!ELEMENT 书籍列表 ANY>]><书籍列表> <计算机书籍> 等等。。。 </计算机书籍></书籍列表>
上面程序看起来是一个有效的XML文档,但是DTD中仅定义了一个<书籍列表.../>元素,意味着该XML文档中不应该包含其他元素。事实上,该XML文档中还出现了相当多的其他元素。DTD必须定义XML文档中允许出现的所有元素。
<?xml="1.0" encoding="GB2312" standalone="yes"?><!DOCTYPE 书籍列表[ <!ELEMENT 书籍列表 ANY>]><书籍列表> 书籍列表 <!-- 这个是有效的 --></书籍列表>
2、字符串值:这种元素只能是字符串,不能包含其他子元素,也不可以是空元素;
<!-- 定义字符串内容元素 --><!ELEMENT 元素名 (#PCDATA)>
一旦在DTD中使用了(#PCDATA)定义了某个元素类型,就以为元素内容只能是字符串,绝不可包含子元素。
3、空元素:这种元素只能是空元素,既不可以包含子元素,也不可以包含字符串值;
<!-- 定义空元素语法 --><!ELEMENT 元素名 EMPTY>
<?xml="1.0" encoding="GB2312" standalone="yes"?><!DOCTYPE 书籍列表[ <!ELEMENT 书籍列表 EMPTY>]><书籍列表/>
4、包含子元素:包含子元素的元素比较复杂,因为需要详细定义子元素之间的顺序和子元素出现的次数等;
5、混合类型:指定XML元素的值只能是几个确定的类型,混合类型是比任意类型更强的约束,但又能提供和任意类型大致相当的功能
<!-- 定义混合元素 --><!ELEMENT 父元素名 (#PCDATA | 子元素1 | 子元素2 | 子元素3 ...)*>
不管是那种类型的XML元素,都可以添加任意多个属性,即使空元素也可添加一个或多个属性,只是添加属性实必须指定属性值。
定义子元素
有序的子元素
如果使用英文逗号作为子元素直接的分隔符,则子元素直接必须遵守所定义的顺序
<?xml="1.0" encoding="GB2312"?><!ELEMENT 书籍列表 (计算机书籍)*><!--逗号相隔就必须严格按照顺序要求--><!ELEMENT 计算机书籍 (书名, 作者, 价格, 简要介绍)><!ELEMENT 书名 (#PCDATA)><!ELEMENT 作者 (#PCDATA)><!ELEMENT 价格 (#PCDATA)><!ELEMENT 简要介绍 (#PCDATA)>
互斥的子元素
互斥的子元素表明子元素只能出现其中之一,用竖线分隔
<?xml="1.0" encoding="GB2312"?><!ELEMENT 书籍列表 (计算机书籍)*><!ELEMENT 计算机书籍 (书名|作者| 价格| 简要介绍)>
子元素出现的频率
+ :表明子元素可以出现一次或者多次
* :表明子元素可以出现0次或者多次
?:表明子元素可以出现0次或者一次
组合子元素
就是把元素组成元素组,用括号组起来。
无序子元素
<!ELEMENT 计算机书籍 (书名 | 作者 | 价格 | 简要介绍)+>
上面程序,4个元素每次只能出现其中之一,然后使用加号,标识该组元素可能出现1次或者多次。
定义元素的属性
元素除了可以包含子元素之外,还可以添加属性:
<水果 品名="桃子" 颜色="粉红">关于水果的元素</水果>
DTD也为XML元素添加属性提供支持
<!ATTLIST 属性所属的元素 属性名 属性类型 [元素对属性的约束] [默认值]>
在上面语法中,“元素对属性的约束”和“默认值”两个部分是可选的,对它们的使用有如下几种情况:
1、在没有指定“元素对属性的约束”时,必须为该属性指定“默认值”;
2、当“元素对属性的约束”是#REQUIRED,不能指定“默认值“;
3、当“元素对属性的约束”是#IMPLIED,不能指定“默认值”;
4、当“元素对属性的约束”是#FIXED,必须指定“默认值”。
XML文档中可能包括多个属性,DTD需要使用多个<!ATTLIST...>定义属性,元素对属性的约束规则有如下几种:
1、#REQURED:必须的属性,意味着必须为该元素提供属性;
2、#IMPLIED:可有可无的;
3、#FIXED:该属性的值是固定的,定义的时候必须指定固定值。使用该元素时无须为其分配该属性。XML处理器将自动为该属性增加固定值。
定义属性类型
DTD支持的属性类型
CDATA、 (en | en1 | en2) 、 ID、 IDREF、IDREFS、NMTOKEN、NMTOKENS、ENTITY、ENTITIES、NOTATION、 xml:
定义实体
所谓实体就是用一个字符串代替另一个字符串
实体有如下作用:
1、提高代码复用,方便修改、维护XML文档。
2、使用某些特殊的符号,这些特殊的符号可能会使XML解析器混淆。
3、减少字符输出量,如果某个字符串特别长,而且需要经常使用,则可以定义为实体。
定义实体之后,该实体既可以在XML文档中引用,也可以在DTD本身中引用。
定义实体
<!--普通实体是在XML文档中使用的实体,定义普通实体语法如下--><!ENTITY 实体名 "实体值"><!--使用实体的语法格式-->&实体名;
定义实体参数
还有一种实体在DTD中使用,这种实体被称为参数实体,定义和使用参数实体和普通实体由小小的差别。
定义参数实体的语法格式如下:
<!ENTITY % 实体名 “实体值”><!--使用实体-->%实体名;
外部实体
实体类似于宏变量,也就是为一段字符数据起一个短名。
定义实体时直接为实体指定对应值,这种方式定义的实体称为内部实体。
与内部实体对应的是外部实体,外部实体的语法格式如下:
<!ENTITY 实体名 SYSTEM "实体值所在的文件的URI">
外部实体参数,语法格式如下:
<!ENTITY % 实体名 SYSTEM | PUBLIC ["公用实体标识名"] "实体所在文件URI">
定义符号
XML文档只是一个文本文件,它无法处理更复杂的数据类型,比如:图片、声音等,因此XML文档将不负责处理这些数据,而是通过定义一个符号来标识这些数据。
定义符号有两种语法格式,分别用于定义普通符号和公共符号。
定义普通符号的语法如下:
<!NOTATION notation SYSTEM "value">
定义公共符号的语法如下:
<!NOTATION notation PUBLIC "name" "value">
由于符号用于标识XML文档中的外部数据,因此符号值通常由如下两种形式:
1、MIME(多用途Internet邮件扩展)类型:一般说来,通用MIME类型的文件总是由相应的程序负责处理
2、外部程序所在路径:这种方式直接指定某个外部程序负责处理XML文档中的外部数据。
不管采用哪种方式定义符号,其实质是一样的:当XML文档中包含某些非文本格式的数据时,可以使用符号表明这些数据应该由何种外部程序员处理。
XMl解析器本身不负责处理非文本格式的数据,而是调用符号所指定的外部程序来对其进行处理。
符号通常由两个用途:
1、定义未解析实体
2、作为NOTATION类型的属性的值
未解析实体
所谓外部实体就是专门定义一个外部文件来保存实体的值,。
保存外部实体值的外部文件都满足如下两个要求:
1、该外部文件是一个文本文件;
2、该外部文件是满足XML要求的结构化文档。
如果不满足上面两个条件,那么XML文档就无法解析该外部文件里的内容,这时就只能将该外部实体声明为未解析实体。
XML解析器不能处理未解析实体所对应的数据,因此XML文档不能像引用普通实体一样直接引用未解析实体,而需要通过ENTITY、ENTITIES类型的属性来调用。
定义未解析实体的语法格式如下:
<!ENTITY % 实体名 SYSTEM | PUBLIC ["公用实体标识名"] "实体值所在文件的URI" NDATA notation>
XML