首页 > 代码库 > xml入门
xml入门
1.常见用途
(1) 数据传送通用格式
比如qq之间的数据传送做案例进行详细讲解,用xml格式来传送数据,具有良好的可读性性,可维护性。
(2)配置文件
xml文件做配置文件可以说非常的普遍,比如我们的tomcat服务器的server.xml ,web.xml 。 在比如我们的struts中的struts-config.xml文件,和hibernate的hibernate.cfg.xml .....
(3) 充当小型数据库
xml文件做小型数据库,也是不错的选择,我们程序中可能用到一些经常要人工配置的数据,如果放在数据库中读取不合适(因为你要增加维护数据库工作),则可以考虑直接用xm来做小型数据库【比如msn中保存用户聊天记录就是用xml文件的】,而且直接读取文件显然要比读取数据库快。
2.Xml语法
入门案例: 用xml来记录一个班级信息
? 编码问题:
ansi 是 american national standard insititu 美国国家标准协会 。
ansi 编码在不同的国家是不一样的,更确切的说是和操作系统的语言是一直的,例如我们现在用的操作系统是简体中文版,即gb2312,则此时ansi编码的表现形式就是gb2312。但是如果你使用的是繁体中文则ansi的表现形式就是gbk或者big5。如果你使用的操作系统韩语版的,则ansi的表现则为韩文操作系统默认的编码。所以在xml中定义编码(encoding)的时候,一定要和文件的编码方式一直,否则会出错:
(1) 文档声明
<?xml version=”1.0” encoding=”编码方式” standalone=”yes|no”?>
XML声明放在XML文档的第一行
XML声明由以下几个部分组成:
version - -文档符合XML1.0规范,我们学习1.0
encoding - -文档字符编码,比如”gb2312”
standalone - -文档定义是否独立使用
standalone="yes“
standalone=“no” 默认
(2) 一个xml 文档中,有且只有一个根元素(元素==标签==节点)
(3) 对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的:
<name>xiaoming</name>
不等价与
<name> xiaoming</name>
由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,要特别注意。
(4) 属性值用双引号(")或单引号(‘)分隔(如果属性值中有‘,用"分隔;有",用‘分隔),一个元素可以有多个属性,它的基本格式为:<元素名 属性名="属性值">
特定的属性名称在同一个元素标记中只能出现一次,属性值不能包括<, >, &
特别说明: 如果属性值有单引号,又有双引号,则需要使用实体: html-> ©
特殊字符 | < | > | & | " | ‘ |
---|---|---|---|---|---|
实体 | < | > | & | " | ' |
一个XML元素可以包含字母、数字以及其它一些可见字符,但必须遵守下面的一些规范:
区分大小写,例如,<P>和<p>是两个不同的标记。
不能以数字或"_" (下划线)开头。
不能包含空格。
名称中间不能包含冒号(:)。
(5) CDATA节
有些内容可能不想让解析引擎解析执行,而是当作原始内容处理,用于把整段文本解释为纯字符数据而不是标记的情况。包含大量<、>、&或者"字符。CDATA节中的所有字符都会被当作元素字符数据的常量部分,而不是XML标记。
语法:
<![CDATA[
……
]]>
可以输入任意字符(除]]>外),不能嵌套
有时我们希望传递一些特殊字符, <>@!#$%^&*( 可以使用 CDATA节包括)
<intro><![CDATA[这个是好$$128qw8o8<Lk;>;akdf0sa98u329408><<K>>>学生]]></intro>
面试题:
问; 如何适用xml 去传递小图片
答: 可以把文件读取成一个byte[] ,然后放到 CDATA节,再传递.
xml语法小结:
XML声明语句
<?xml version="1.0" encoding="gb2312"?>
必须有且仅有一个根元素
标记大小写敏感
属性值用引号
标记成对
空标记须关闭
元素正确嵌套
名称中可以包含字母、数字或者其它字符
名称中不能含空格
名称中不能含冒号(注:冒号留给命名空间使用)
3. dtd(xml文件约束)
3.1基本概念
dtd ( document type definition 文档类型定义),该文件一般和xml文件配合使用, 主要的用途是约束xml, 除了dtd 技术外,还有一个schema的技术也可以用于约束xml文件的书写规范.
3.2问题引出及解决:
怎么能给一个人添加一个面积元素呢?由于现在的xml处于自由状态,没有受到任任何约束,所以想怎么写就怎么写,所以就可以使用dtd来限制它。
解决xml过于自由的问题:->dtd
3.3 dtd和xml的关系:
3.4 dtd元素
3.4.1语法
示例:
因为我们设定person元素必须为空。而在xml文件中我们给它添加了子元素。
3.4.2 dtd的元素的修饰符
3.5 dtd元素属性
基本语法
属性的类型有五种:
CDATA 表示可以放入文本
ID 表示属性的值,不能重复,同时不要用数字开头.
IDREF/IDREFS 当一个元素的属性值,需要去引用另外一个ID ,则使用IDREF,如果希望引用多个,则使用IDREFS,请用空格隔开.
Enumerated 表示属性的值,只能是例举出了的。
属性的特点有四种
#REQUIRED 表示必须有
#IMPLIED 表示可以有
#FIXED “值” 表示如果有,则必须是什么
Default “值” 表示如果不指定,则默认.
如:
实体(ENTITY)
实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
就像在java 中,我们定义了一个字符串:
String str=”你好”;
这样,在别的地方,我们使用str就可以访问到 ‘你好’
在DTD定义中,一条<!ENTITY …>语句用于定义一个实体。
实体可分为两种类型:引用实体和参数实体。
引用实体
引用实体主要在 XML 文档中被应用
语法格式(dtd中定义):
<!ENTITY 实体名称 “实体内容”>
引用方式(xml中引用)
&实体名称;
案例
在 dtd 中定义:
<!ENTITY mycopy "我的公司版权">
注:最好把定义放在dtd的最后
在xml中使用:
&mycopy;
参数实体
参数实体被 DTD 文件自身使用
语法格式:
<!ENTITY % 实体名称 "实体内容" >
引用方式:
%实体名称;
示例1:
示例2:
<!ENTITY % 实体名称 "实体内容" >
3.6 快速入门案例
Xml1.dtd
Xml1.xml
注:现在可能还看不懂一些里面的东西,我们后面会一一说明的。
编程校验XML文档正确性(xmlspy) :
IE5以上浏览器内置了XML解析工具:Microsort.XMLDOM,开发人员可以编写javascript代码,利用这个解析工具装载xml文件,并对xml文件进行dtd验证。
创建xml文档解析器对象:
这样我们就可以检测我们的xml是否有误了:
由于,我们刚才写的Xml1.xml是符合dtd规则的。所以该html显示为:
随着后面的讲解,我们会把错误显示出来的。
3.7 dtd 的分类
(1)内部 dtd
注意:例中的定义关键字一定要大写,如DOCTYPE、ELEMENT、#PCDATA,且元素名称与数据类型之间也要有空格。
(2)外部 dtd
dtd文件:
xml文件:
3.8 在xml中引入dtd 的方法
(1)内部dtd
不用引入。
(2)外部dtd
<1>引入本地 dtd
<!DOCTYPE 根元素 SYSTEM ‘地址’>
<2> 引入公共的 dtd
<!DOCTYPE 根元素 PUBLIC ‘url地址’>
<3>内外部dtd
<!DOCTYPE 根元素 SYSTEM "DTD文件路径" [ 定义内容 ]>
3.9 学习dtd的目标
一般公司很少让程序员自己写 dtd,要求程序员看的懂dtd,同时可以根据给出的dtd,写出对应的xml
3.10 DTD的局限性
DTD语法与XML语法存在差异;
缺少对XML名称空间的支持;
缺少数据分类;
内容模型描述收到限制。
4. xml 命名空间
用途:XML 命名空间提供避免元素命名冲突的方法。
4.1 问题的引出
xml1.xml
xml2.xml
当xml1.xml和xml2.xml放在一起使用的时候,我们便分不清,table到底代表xm1.xml中定义的还是xml2.xml中定义的那个。
因此,在 XML 中,当两个不同的文档使用相同的元素名,并且它们放在一起使用时,由于两个文档都包含带有不同内容和定义的相同名称的元素,就会发生命名冲突。
4.2 解决之道
4.3定义
这样我们就可以使用前缀h来限定元素的确切含义了。
默认命名空间的定义:
注:用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。改地址有一个响亮的名字:URI(统一资源定位符)。URI最大的特点就是唯一性。
5. XML Schema(XSD)
XML Schema 是基于 XML 的 DTD 替代者。
XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。
XSD能干什么:
定义可出现在文档中的元素
定义可出现在文档中的属性
定义哪个元素是子元素
定义子元素的次序
定义子元素的数目
定义元素是否为空,或者是否可包含文本
定义元素和属性的数据类型
定义元素和属性的默认值以及固定值
由此可见,XSD比DTD厉害的多啊,那我们还需要DTD吗?
非常需要!因为:(1)XSD没有提供ENTITY功能。但是在很多的xml中ENTITY占有很重要的地位,如,RDF,OWL中;(2)DTD是XML推荐标准里唯一的定义和验证方法。
遵守某个特定的XML Schema的XML文件称为XML Schema的一个实例文档。
5.1 快速入门
schema的功能和dtd的功能一样,都是用来限制xml的。所以我需要在xml文件中插入schema文件的引用。为了能在编写xml是得到只能提示,我就在的spring的配置文件(applicationContext.xml)里面编写xml(应该有比较简便的放xml智能提示,有知道的大侠,望不吝赐教):
首先在MyEclipse中新建一个web工程,并加入spring框架,applicationContext.xml一般在src目录下,为了简便起见,我们就在src目录下创建我们的Schema文件——name.xsd,内容如下(先不要管内容是什么意思,后面会一一讲解):
然后打开实例文档(applicationContext.xml),在这个文件里面编写我们的待检验文件,首先引入Schema文件,
然后我们编写xml文件时,便有提示功能:
通过编写代码来验证xml文件的正确性:
Schema文档中,element元素定义了实例文档中可以含有的元素,attribute元素定义了实例文档中特定元素含有的属性,type属性表示对应的实例文档中对应的元素或属性的类型。
5.2 <schema>声明
XML Schema 文件的跟元素是<schema>该元素中包含如下属性:
我们只说几个重点的属性:
首先来看version,这个属性是一个非常简单的属性,用来标记XML Schema的版本。
targetNamespace(目标命名空间):XML Schema主要是用来声明在其实例文档中可以使用的词汇的。而这些词汇就是由targetNamespace属性里指定的一个命名空间来标识的。当声明一个targetNamespace属性时,就一定要插入友好的命名空间声明,如:
xmlns:target="http://www.example.com/name"targetNamespace="http://www.example.com/name"
或者使用默认命名空间声明,如:
<xsd:schema xmlns="http://www.example.com/name"targetNamespace="http://www.example.com/name"
elementFormDefault、attributeFormDefault表示元素或属性的限定方式,有两种即限定和不限定。如果一个元素或者属性关联到一个命名空间,就是限定的。反之则是不限定的。如,下面就是限定的:
非限定的就比如:
利用这两个属性就可以控制实例文档中元素和属性的默认限定值。它们默认值都为"unqualified"(非限定的)。
5.3 <element>声明
(1)元素的类型
元素的内容的类型是有type属性决定的。根据类型定义的位置的不同,该类型可分为两种:全局类型与局部类型。
Schema中其他的声明也一样,根据定义的位置的不同可分为全局声明和局部声明。
全局声明:<schema>为其直接父亲,可以在整个XML Schema中被重用。
局部什么:<schema>为其祖先但并非直接父亲,只能在指定的上下文中使用。
(2)默认值和固定值
我们可以通过default和和fixed属性为元素设定默认值和固定值。如:
1 <xsd:element name="last" type="xsd:string" default="Doe"/>
则在实例文档中
<last></last>或者<last/>
将被解析为<last>Doe</last>
当我们希望某些元素的值不能变化的时候就用fixed将其设定为固定值。
1 <xsd:element name="version" type="xsd:string" fixed="1.0"/>
这时,实例文件中如下的形式是合法的:
下面的形式就是非法的:
1 <version>2.0</version>
(3)元素通配符
包含任何命名空间中的元素的声明称为通配符。利用通配符可以把一个命名空间里的任何一个元素插入到XML Schema中。
声明一个元素通配符要用到<any>,它只能声明在内容模型中,不允许创建全局<any>。<any>声明还可以用来控制元素来自哪个或那些命名空间,为此需要namespace属性,namespace的允许取值为:
我们还可以通过processContents属性来指示模式验证器采用何种方式验证实例文档:
strict(默认值):处理器验证通配符元素。如果验证器找不到通配符元素的全局XML Schema定义,则模式验证器报错;
lax:如果处理器可以访问到通配符的全局XML Schema定义,则验证这些通配符元素;
skip:处理器将忽略实例文档中所有的通配符元素。
5.4 <attribute>声明
属性的声明格式如下:
与元素一样,属性也可以分为全局属性和局部属性。定义方式和定义元素的一样。
(1)属性的使用
通过use属性来指定属性在实例文档中出现的方式:
required:必须出现
prohibited:禁用的
optional(默认值):可以出现也可以不出现
如果我们为一个属性定义了默认值,那么use的取值就不能是required和prohibited了。
(2)属性通配符
和元素通配符一样。用来包括来自一个命名空间的任何属性的声明称为属性通配符。
声明一个属性通配符:
它只能声明在<complexType>或者<attributeGroup>声明内,不能建立全局<anyAttribute>声明。
其中,namespace的允许取值:
processContents属性的用途及机制和属性的一样。
例,希望包含任何非限定属性以及来自http://www.w3.org/XML/1998/namespace命名空间的属性。用属性通配符实现如下:
5.5 Schema中的类型
Schema中主要包括三种部件:元素(element)、属性(attribute)、注释(notation)。
这三种基本的部件还能组合成以下的部件:
a)类型定义部件: 简单类型和复合类型
b)组部件
c)属性组部件
5.5.1 简单类型
XML Schema中定义了一些内建的数据类型,这些类型可以用来描述元素的内容和属性值。
定义:一个元素中如果仅仅包含数字、字符串或其他数据,但不包括子元素,这种被称为简单类型。如同上述代码中元素quantity就是一个简单类型。它的元素内容必须是非负整数,不包括任何属性和子元素。
所有内建的简单类型
原始类型
string,boolean,decimal,float,double,duration,datetime,time,date,gYearMonth,gYear,gMonthDay,dDay,gMonth,hexBinary,base64Binary,any URI,QNameNOTATION
衍生类型(括号中为基类型)
normalizedString(string),language(tonken),token(normalizedString),NMTOKEN(token),Name(token),NCName(Name),ID(NCName),IDREF(NCName),IDREFS(list of IDREF),ENTITY(NCName),ENTITIES(list of ENTITY),integer(decimal),nonPositiveInteger(integer),negativeInteger(noPositiveInteger),long(integer),int(long),short(int),byte(short),nonNegativeInteger(integer),unsignedLong(nonNegativeInteger),unsignedInt(unsignedLong),unsignedShort(unsignedInt),unsignedByte(unsignedShort),positiveInteger(nonNegativeInteger)
创建简单类型
我们先创建了一个简单类型:quantityType,它是从integer继承过来的,minInclusive和maxInclusive定义了它的最小值2和最大值5。最后我们定义元素quantity的类型为quantityType。
使用restriction我们可以限制只能接受一定数值或者只能接受一定文字,
基本方面:equal,ordered,bounded,cardinality,numeric限制方面:length,minLength,maxLength,pattern,enumeration,whiteSpace,maxInclusive,maxExclusive,minInclusive,minExclusive,totalDigits,fractionDigits
例1:
通过enumeration来列出所有的城市名称,取值是只能取里面列出的城市名。
5.5.2 列表类型
list可以用来定义列表类型,listOfIntType这个类型被定义为一个xsd:int的列表,元素IntList的值可以是几个整数,它们之间使用空格隔开。
正确: <listOfMyInt>1 5 15037 95977 95945</listOfMyInt>
错误: <listOfMyInt>1 3 abc</listOfMyInt>
5.5.3 联合类型
用union来定义了一个联合类型,里面的成员类型包括ChinaCity和listOfIntType,应用了联合类型的元素的值可以是这些原子类型或列表类型中的一个类型的实例,但是一个元素实例不能同时包含两个类型。
5.5.4匿名类型定义
前面我们在定义元素类型时总是先定义一个数据类型,然后再把元素的type设成新定义的数据类型。如果这个新的数据类型只会用一次,我们就可以直接设置在元素定义里面,而不用另外来设置。如图中元素quantity的类型就是一个从1到99的整数。
这种新的类型没有自己的名字的定义方法我们称之为匿名类型定义。
5.5.5 复合类型
前面我们所说到的都是属于简单类型,即元素里面只有内容,不再包括属性或者其它元素。接下来我们要让元素里面包含属性和其它元素,称之为复合类型。
我们用complexType表示这是一个复合类型(这里我们是用匿名类型定义的)。simpleContent表示这个元素下面不包括子元素,extension表示这个元素值是decimal的,attribute来设置它的一个属性currency,类型为string.
<internationPrice currency="str">3.1415926</internationPrice><!-- 正确 –>
5.5.6混合内容
同样,我们采用了匿名类型方式来定义一个元素salutation。我们注意到在complexType后面多了一个mixed="true",这表明这是一个混合类型:里面既有元素本身的内容,又有其它子元素。name元素就是salutation的子元素。
sequence表示子元素出现的顺序要和schema里面的顺序一样。
参考资料:
1. 韩顺平xml视频教程
2. XML认证教程,第 6 部分: XML Schema
3. xml入门经典
xml入门