XML的全称是Extensible Markup Language,即可扩展标记语言,它由SGML(Standard Generalized Markup Language)发展而来,允许开发者自由定义标签,可以将标签和内容有效分离。不同于HTML,XML不再侧重于数据如何表现,而是更多地关注数据如何存储和传输。因此它组建成为一种跨平台的数据交换格式,一种轻量级的持久化方案。通过使用XML,开发者可以在不同系统之间进行数据交换,还可以将程序状态保存到XML文件中,而无须使用关系数据库。
XML广泛应用与javaEE开发的各个方面,绝大部分java应用和框架都在使用XML作为配置文件来管理各java组件,java作为最流行的跨平台编程语言,不可避免地需要在不同平台之间进行数据交换,而XML则为这种数据交换提供了支持。除此之外,XML还是WebService技术的重要基础,而WebService技术则是异构系统整合的重要手段,甚至为SOA(面向服务的架构)也提供了底层技术实现。由此可见,对于实际企业开发具有举足轻重的作用。
和HTML相比,XML具有简单易用,扩展性好等特点,而且XML语言严格要求嵌套、配对,并遵守语义约束,结构清晰,数据逻辑和现实逻辑分离,XML文件需要特定的程序的进行处理。下面找一个案例文件来看看XML的整体结构:
<?xml version="1.0" encoding="GB2312" standalone="no"?>
< 专有名词列表 >
< 专有名词 >
< 名词 >XML </ 名词 >
< 解释 >XML是一种可扩展的源置标语言,它可用以规定新的置标规则,并根据这个规则组织数据 </ 解释 >
< 示例 >
<!-- 一个XML的例子 -->
<![CDATA[
<联系人>
<姓名>张三</姓名>
<EMAIL>zhang@aaa.com</EMAIL>
</联系人>
]]>
</ 示例 >
</ 专有名词 >
</专有名词列表>
一个XML文件基本组成是:
XML声明
处理指示(可选)
XML元素
一)声明
典型的XML文件的文件声明如下:
<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
<? ?>为处理指令, 如<?xml-stylesheet type="text/css" href="config.css" ?> standalone表示文档是否需要引用其他资源,该属性只接受yes或者no两个值。encoding表示对该文档进行解码所用的字符集。xml使用 <!-- 注释 -->来进行注释,注释不能嵌套,如果有声明的话,则在声明前不能有注释。
二)元素
元素即为标签,通常由开始标签、元素内容和结束标签组成,例如<name>jobs</name>,一个文件只有一个根标签,元素必须合理结束。
空格和换行都可以作为原始内容被处理,对于XML文档而言是区分大小写的。
如果元素有属性值的话要用双引号(“)或者单引号(‘) 包起来。
一些特殊符号如> ,<等不会被正确解析,为了正确处理这些字符XML允许使用实体来表示这些特殊字符,其内置了5个实体引用:
< < || > > || & & || ' ' || " "
如果本身内容需要解析引擎解析,这需要使用特殊标记 CDATA,其正确使用方法为:
<![CDATA[ 需要显示的内容 ]]>
关于注释,XML的注释中不能出现”-“ 或者”--“,容易与”-->“ 结束标记混淆,不要把注释放在标记之中,此外注释不可以嵌套。
对于一个有效且格式良好的XML文档,必须有语义约束, 语义约束可以规定XML文档出现哪些元素,各元素之间的父子关系,以及每个元素内部都可以出现哪些子元素。可以支持哪些属性等。如果提供更先进的语义约束,还可以约束XML文档内各元素和各属性的数据类型等。目前有两种文档定义语义约束方式,一种是采用DTD作为语义约束,另一种是采用XML Schema作为语义约束。
一)采用DTD约束
XML的语义约束其实是一段代码,如:
<!DOCTYPE 元素名[
元素描述
]>
该代码可以放在XML文件中,也可以单独放在一个文件中,如果单独放在一个文件中,该文件被称为约束文件,扩展名为.dtd。文档约束定义之后,我们需要自己引入到XML文件中来,当然内部DTD直接就在文件中了,若是外部DTD则需要使用形如如下声明格式引用:
<!DOCTYPE 根元素名 SYSTEM “DTD文件的URI” >
DTD文件的URI可以使用绝对路径,也可使用相对路径,这种外部DTD文件,可以被多个XML文件共享 。
而大部分时候我们使用的DTD都是公用的DTD文件,由某个权威机构或者特定行业制定的,此DTD文件我们需要使用如下声明格式引用:
<!DOCTYPE 根元素名 PUBLIC “DTD的标示名” “公用DTD的URI” >
1)对元素的约束
元素类型定义的全称是Element Type Definition,简称ETD,ETD的语法格式如下:
<!ELEMENT 元素名 元素类型描述 >
有下列几种情况:
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人 (姓名) >
<!ELEMENT 姓名 (#PCDATA) >
<!ELEMENT 联系人 (姓名 EMAIL) >
<!ELEMENT 联系人 (姓名,EMAIL) >
<!ELEMENT 联系人(姓名,EMAIL+)>
<!ELEMENT 联系人(姓名,EMAIL*)>
<!ELEMENT 联系人(姓名,EMAIL)+>
<!ELEMENT 联系人(姓名,(电话|EMAIL))>
<!ELEMENT 联系人(姓名,(电话|EMAIL),地址?)>
<!ELEMENT 联系人(姓名|电话|EMAIL|#PCDATA)*>
<!ELEMENT HR EMPTY>
对于正则表达式的形式,“+” 表示1或多,“?”表示 0或1,“*” 表示0或多,“,”表示有顺序,“|”表示或
2)属性的约束
对于属性的约束格式如下:
<!ATTLIST 属性所属的元素 属性名 属性类型 [元素对属性的约束] [默认值] >
其中元素对属性的约束有四种,#REQUIRED,#IMPLIED,#FIXED,默认值
#REQUIRED:必需的属性,意味着必需为元素提供该属性,如 <!ATTLIST 作者 地址 CDATA #REQUIRED >
#IMPLIED:该属性是可有可无的。
#FIXED:该属性的值是固定的,定义时必须指定固定值,如 <!ATTLIST 作者 地址 CDATA #FIXED "北京" >
如果是#FIXED,则必需指定默认值,其他则不需要。
对于属性类型,DTD支持的属性类型很多,如CDATA,ENUMERATED,ID,ENTITY,NMTOKEN,NOTATION等等,而对于实体(ENTITY)来说,DTD中有两种实体,一般实体和参数实体,两种实体的引用方式如下:
一般: <!ENTITY 名称 “内容” > ; 而参数实体 , <!ENTITY % 名称 “内容” >
如要声明为外部实体则需添加SYSTEM,如DTD引入类似,引用实体时,需要使用 “&实体名”。 举例如下:
<!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址">
<!ELEMENT 个人联系信息 (%TAG_NAMES; | 生日)>
<!ELEMENT 客户联系信息 (%TAG_NAMES; | 公司名)>
二)采用XML Schema约束
XML Schema提供了比DTD更强的语义约束,不仅可以定义XML文档的结构,还可以规范文档的内容。XML Schema本身就是一个XML文档,其基于标签的语法比DTD的可读性更强。由于Schema约束相当的复杂,本文只介绍简单部分,也是笔者学习时的内容,力求能读懂XML约束文件,常见的XML文件不会感到生疏即可。
在Schema文档中它有一个根元素就是schema,编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,在XML Schema技术中有一个专业术语来描述这个过程,即把XML Schema文档声明的元素绑定到一个名称空间上,以后XML文件就可以通过这个URI(即名称空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束。在XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)表示。
Schema约束采用为来自不同模式文件的元素添加前缀,来代替不同的命名空间,来解决名称冲突问题。一个没有使用命名空间的Schema文件,也可以导入XML文档中。xmls[:xxx]用于为指定XML文档引入语义约束,XXX便是约束对应的命名空间。
下面看一下Schema的例子:
<?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: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>
<schema>元素是每一个XML Schema的根元素,XML Schema约束文件类似如下:
<?xml version="1.0"?>
<xs:schema>
. .. ...
</xs:schema>
xmlns:xs=http://www.w3.org/2001/XMLSchema 说明了schema用到的元素和数据类型来自的命名空间。
targetNamespace="http://www.w3school.com.cn"显示被此schema定义的元素(note,to,from,heading,body)来自命名空间:"http://www.w3school.com.cn"。
xmlns="http://www.w3school.com.cn" 指出默认命名空间为:http://www.w3school.com.cn
elementFormDefault="qualified" 指出任何XML实例文档所使用的且在此schema中声明过的元素必须被命名空间限定。
如下是在XML文档中使用该约束时便可以这样写:
<?xml version="1.0"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
xmlns=http://www.w3school.com.cn告诉schema验证器,在此XML文档中使用的所有元素都被声明于"http://www.w3school.com.cn"这个命名空间。一旦拥有了可用的XML Schema实例命名空间:xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 就可以使用schemaLocation属性了。此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的XML schema的位置:
xsi:schemaLocation=http://www.w3school.com.cn note.xsd
1)用Schema定义元素及其内容
XSD的元素有简易元素和复合元素,简易元素指那些仅包含文本的元素。它丌会包含任何其他的元素戒属性。也可向数据类型添加限定(即facets),以此来限制它的内容,戒者您可以要求数据匹配某种特定的模式。
如下定义方法: <xs:element name="xxx" type="yyy"/>
常用类型有xs:string; xs:decimal; xs:integer; xs:boolean; xs:date; xs:time。
如: <xs:element name="age" type="xs:integer"/>
加上默认值之后:<xs:element name="color" type="xs:string" default="red"/> ,固定值使用fixed。
2)用Schema定义属性及其内容
所有的属性均作为简易类型来声明 ,简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。
如下定义方法:<xs:attribute name="xxx" type="yyy"/>
如下列子:<xs:attribute name="lang" type="xs:string" default="EN"/> 此处使用了默认值。
<xs:attribute name="lang" type="xs:string" use="required"/> 规定属性为必选。
3)限定facet
通过XSD可以对元素或者属性进行限定,这些限定被称为facet ,如下列子对大小范围的限定:
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
当然还可以使用<xs:enumeration ...>一组值,<xs:pattern .....> 一系列值, <xs:whiteSpace.....> 空白字符,<xs:length....> 长度等等对数据类型的限定。
下面讲述复合元素的使用情况:
11)复合元素指包含其他元素及/或属性的XML元素,一个例子如下:
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
如下XSD写法:
<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"元素可以使用type属性,这个属性的作用是引用要使用的复合类型的名称,这是需要在complexType 加入type属性,type属性可以共享。
还可以在已有的复合元素乊上以某个复合元素为基础,然后添加一些元素,如下方法:
<xs:complexType name="personinfo">
..........................
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
。。。。。。。。。
</xs:extension>
</xs:complexContent>
</xs:complexType>
22)复合类型指示器
通过指示器,我们可以控制在文档中使用元素的方式。常见的有7种指示器:
Order指示器:
All, 用于定义元素的顺序;
Choice,规定可出现某个子元素戒者可出现另外一个子元素(非此即彼);
Squence ,规定子元素必须按照特定的顺序出现
Occurrence指示器:
maxOccurs指示器可规定某个元素可出现的最大次数,minOccurs指示器可规定某个元素能够出现的最小次数.如需使某个元素的出现次数丌受限制,请使用maxOccurs="unbounded"这个声明.
Group 指示器: Group name,attributeGroup name,Group指示器用于定义相关的数批元素。
此外Schema还有全局元素,本地元素,替换等机制,以及各类数据类型的扩展,和DTD有点类似,在此就不一一介绍了。