@liayun
2016-06-28T16:40:21.000000Z
字数 10594
阅读 2073
JavaWeb
XML语言出现的根本目标在于描述上图那种,在现实生活中经常出现的有关系的数据。
在XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在开始标签和结束标签之间,又可以使用其它标签描述其它数据,以此来实现数据关系的描述。例如:
<?xml version="1.0" encoding="UTF-8"?>
<中国>
<北京>
<海淀></海淀>
<朝阳></朝阳>
</北京>
<福建>
<福州></福州>
<龙岩></龙岩>
</福建>
<湖北>
<武汉></武汉>
<天门></天门>
</湖北>
</中国>
在一个软件系统中,为提高系统的灵活性,它所启动的模块通常由其配置文件决定。
例如一个软件在启动时,它需要启动A、B两个模块,而A、B这两个模块在启动时,又分别需要A1、A2和B1、B2模块的支持,为了准确描述这种关系,此时使用XML文件最为合适不过。
<?xml version="1.0" encoding="UTF-8"?>
<soft>
<a>
<a1></a1>
<a2></a2>
</a>
<b>
<b1></b1>
<b2></b2>
</b>
</soft>
一个XML文件分为如下几部分内容:
最简单的声明语法:
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码,即告诉浏览器用哪个编码表来解析文档。
<?xml version="1.0" encoding="GB2312" ?>
当XML文件中有中文时,必须使用encoding属性指明文档的字符编码,例如:encoding="GB2312"或者encoding="utf-8",并且在保存文件时,也要以相应的文件编码来保存,否则在使用浏览器解析XML文件时,就会出现解析错误的情况。
例如,
<?xml version="1.0"?>
<softCompany>
<company>MicroSoft</company>
<company>google</company>
<company>Apple</company>
<company>百度</company>
</softCompany>
使用“记事本”来保存该xml文件时,没有使用encoding属性来指明文档的字符编码,但文档里面有“百度”这样的中文字符,在使用IE浏览器解析该XML文件时,IE就不知道该使用什么编码去解析该文件,就无法解析了,如下图所示:
要想正确解析该XML文档,就可以使用encoding属性指明该文档的字符编码。例如:
<?xml version="1.0" encoding="UTF-8"?>
<softCompany>
<company>MicroSoft</company>
<company>google</company>
<company>Apple</company>
<company>百度</company>
</softCompany>
并且使用“记事本”保存文件时,也要以相应的文件编码(UTF-8)来保存。此时再次使用IE浏览器来解析该XML文件,就可以正常解析出里面的中文字符了,如下图所示:
用standalone属性说明文档是否独立,即文档在工作的过程中是否依赖于另一个文档。
<?xml version="1.0" encoding="GB2312" standalone="no" ?>
浏览器打开之后,并不会将standalone属性解析出来。
常见错误:
<?xml version="1.0" ?>
问号前面的空格,因为半角状态下的空格,若为全角状态下的空格,即<?xml version="1.0" ?>
,浏览器就解析不出来。编写XML文件常遇到的一个问题——编码错误。
XML文件一般使用国际化通用的编码“utf-8”,所以平时看到的XML文件的头部都会有这样的代码:
<?xml version="1.0" encoding="UTF-8"?>
如果我们使用“记事本”等文本编辑工具编写XML文件时,例如使用“记事本”编写如下的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<CharacterEncoding>
<中国>
<encoding>GB2312</encoding>
<encoding>GBK</encoding>
</中国>
<日本>
<encoding>JIS</encoding>
</日本>
</CharacterEncoding>
当我们在保存文件时,文件的编码默认是以“ANSI”来保存的,如下图所示:
我们编写XML文件时,使用encoding="utf-8"来指明了文档的字符编码,但是在保存的时候却使用了“ANSI”编码来保存文件,由于我们在XML文件中使用encoding="utf-8"来指明了文档的字符编码,所以当浏览器解析该XML文件时,就是使用“utf-8”编码来解析,解析结果如下图所示:
可以看到,浏览器解析失败了,这是为什么呢?我们明明指定了文档的字符编码是“UTF-8”了呀,为什么里面的中文解析不出来呢?这里不得不说说ANSI编码到底代表的是神马意思了。
不同的国家和地区制定了不同的标准,由此产生了GB2312,BIG5,JIS 等各自的编码标准。这些使用2个字节来代表一个字符的各种汉字延伸编码方式,称为ANSI编码。在简体中文系统下,ANSI编码代表GB2312 编码,在日文操作系统下,ANSI编码代表JIS编码。不同ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段ANSI编码的文本中。
下面分析一下为什么IE浏览器无法解析XML文件的原因,如下图所示:
所以千万要记住,使用“记事本”或者“EditPlus”等文本编辑工具编写XML文件时一定要以XML文件的encoding属性指明的编码来保存文件,这样才能保证浏览器解析XML文件时可以正常解析。
上述的问题将CharacterEncoding.xml文件再以“UTF-8”编码保存一次就可以正常解析出CharacterEncoding.xml。
在使用一些比较智能的IDE编写XML文件时,IDE在保存XML文件时,会自动以encoding属性指明的编码来保存文件,例如在Eclipse中编写XML文件时,就可以根据encoding属性指明的字符编码,指明为encoding="GBK"时,保存XML文件时就自动将文件保存成GBK编码,(如图-1),指明为encoding="UTF-8"时,就自动保存为UTF-8(如图-2)。
<a>www.itcast.cn</a>
。<a></a>
,简写为:<a/>
。一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套,例如以下代码就是错误的表率。
<a>welcome to <b>www.it315.org</a></b>
对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。
第一段:
<网址>www.itcast.cn</网址>
第二段:
<网址>
www.itcast.cn
</网址>
由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
<P>
和<p>
是两个不同的标记。一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:
<input name="text">
注意:属性值一定要用双引号(")或单引号(')引起来,定义属性必须遵循与标签相同的命名规范。
在XML技术中,标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如,以上代码又可改写为:
<input>
<name>text</name>
</input>
<!--注释-->
格式。注意:
注释不能嵌套,例如:
<!--大段注释
……
<!--局部注释-->
……
-->
语法:
<![CDATA[
<a>
<a1>中国</a1>
<a2></a2>
</a>
]]>
对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。
特殊字符 | 替代符号 |
---|---|
& | & |
< | < |
> | > |
" | " |
' | ' |
转义字符和CDATA区的区别:
一段XML文档,你要输出给人看,给人看到原始样子,要用转义;你要交给程序处理,把某一段xml文档作为原始内容交给程序处理,就用CDATA区。
处理指令,简称PI (processing instruction)。处理指令用来指挥解析引擎如何解析XML文档内容。
例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容。
config1.css内容为:
#a1 {
font-size: 300px;
color: red;
}
#a2 {
font-size: 100px;
color: green;
}
#b1 {
font-size: 20px;
}
#b2 {
font-size: 200px;
color: blue;
}
config1.xml文档内容为:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<?xml-stylesheet type="text/css" href="config1.css" ?>
<soft>
<a>
<a1 id="a1">中国</a1>
<a2 id="a2">美国</a2>
</a>
<b>
<b1 id="b1">小日本</b1>
<b2 id="b2">英国</b2>
</b>
</soft>
注意:标签名为中文时,css不起作用。
不知为何,我的标签名又不是中文,但css样式还是不起作用?
<?
作为开头,以?>
作为结尾,XML声明语句就是最常见的一种处理指令。 DTD(Document Type Definition),全称为文档类型定义。
举例说明,有一个book.dtd文档如下:
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
注意:DTD文件应使用UTF-8或Unicode编码。
那么按照此DTD约束,写出来的book.xml文档如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
<书>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>39.00元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
PCDATA
即parse character data
(可解析的字符数据),说白了就是字符串。
IE5以上浏览器内置了XML解析工具:Microsort.XMLDOM,开发人员可以编写javascript代码,利用这个解析工具装载xml文件,并对xml文件进行dtd验证。
创建xml文档解析器对象。
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
开启xml校验。
xmldoc.validateOnParse = "true";
装载xml文档。
xmldoc.load("book.xml");
获取错误信息。
xmldoc.parseError.reason;
xmldoc.parseError.line;
以上方法只是了解而已,谁还用这种方法啊!因为Eclipse就可以校验XML文档的正确性。
DTD约束即可以作为一个单独的文件编写,也可以在XML文件内编写。
以上例子是将DTD约束作为一个单独的文件进行编写,现在我们也可以在XML文件内编写。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE 书架 [
<!ELEMENT 书架 (书+)>
<!ELEMENT 书 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
]>
<书架>
<书>
<书名>Java就业培训教程</书名>
<作者>张孝祥</作者>
<售价>39.00元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
XML文件使用DOCTYPE声明语句来指明它所遵循的DTD文件,DOCTYPE声明语句有两种形式:
当引用的文件在本地时,采用如下方式:
<!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">
例如:
<!DOCTYPE 书架 SYSTEM "book.dtd">
当引用的文件是一个公共的文件时,采用如下方式:
<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
例如:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
注意:以上DTD名称不用强记,因为提供给你DTD文件时,就回给你。
在DTD文档中使用ELEMENT声明一个XML元素,语法格式如下所示:
<!ELEMENT 元素名称 元素类型>
元素类型可以是元素内容或类型。
如为元素内容,则需要使用()括起来,如:
<!ELEMENT 书架 (书名,作者,售价)>
<!ELEMENT 书名 (#PCDATA)>
<br/>
,<hr/>
。元素内容中可以使用如下方式,描述内容的组成关系
用逗号分隔,表示内容的出现顺序必须与声明时一致。
<!ELEMENT MYFILE (TITLE,AUTHOR,EMAIL)>
用|
分隔,表示任选其一,即多个只能出现一个。
<!ELEMENT MYFILE (TITLE|AUTHOR|EMAIL)>
元素内容使用空白符分隔,表示出现顺序没有要求
<!ELEMENT MYFILE (TITLE AUTHOR EMAIL)>
在元素内容中也可以使用+、*、?等符号表示元素出现的次数。
+
:一次或多次。例,(书+)
。?
:0次或一次。例,(书?)
。*
: 0次或多次。例,(书*)
。(书)
:书必须出现1次。也可使用圆括号( )批量设置,例:
<!ELEMENT MYFILE ((TITLE*, AUTHOR?, EMAIL)* | COMMENT)>
xml文档中的标签属性需通过ATTLIST为其(标签)设置属性。
语法格式:
<!ATTLIST 元素名
属性名1 属性值类型 设置说明
属性名2 属性值类型 设置说明
……
>
属性声明举例:
<!ATTLIST 商品
类别 CDATA #REQUIRED
颜色 CDATA #IMPLIED
>
对应XML文件:
<商品 类别="服装" 颜色="黄色">…</商品>
<商品 类别="服装">…</商品>
设置说明
举例:
<!ATTLIST 页面作者
姓名 CDATA #IMPLIED
年龄 CDATA #IMPLIED
联系信息 CDATA #REQUIRED
网站职务 CDATA #FIXED "页面作者"
个人爱好 CDATA "上网"
>
属性的类型可以是一组取值的列表,在XML文件中设置的属性值只能是这个列表中的某个值(枚举)。
例,
<?xml version = "1.0" encoding="GB2312" standalone="yes"?>
<!DOCTYPE 购物篮 [
<!ELEMENT 肉 EMPTY>
<!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">
]>
<购物篮>
<肉 品种="鱼肉"/>
<肉 品种="牛肉"/>
<肉/>
</购物篮>
表示属性的设置值为一个唯一值。ID属性的值只能由字母,下划线开始,不能出现空白字符。
例,
<?xml version = "1.0" encoding="GB2312" ?>
<!DOCTYPE 联系人列表[
<!ELEMENT 联系人列表 ANY>
<!ELEMENT 联系人(姓名,EMAIL)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT EMAIL(#PCDATA)>
<!ATTLIST 联系人 编号 ID #REQUIRED>
]>
<联系人列表>
<联系人 编号="a1">
<姓名>张三</姓名>
<EMAIL>zhang@it315.org</EMAIL>
</联系人>
<联系人 编号="a2">
<姓名>李四</姓名>
<EMAIL>li@it315.org</EMAIL>
</联系人>
</联系人列表>
实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
在DTD定义中,一条<!ENTITY …>
语句用于定义一个实体。
实体可分为两种类型:引用实体和参数实体。
语法格式:
<!ENTITY 实体名称 "实体内容" >
引用方式:&实体名称;
。
例,
<!ENTITY copyright “I am a programmer">
……
©right;
注意:还有另一种方式,用一个文档来表示一个实体:
<!ENTITY 实体名称 SYSTEM "外部XML文档的URL" >
语法格式:
<!ENTITY % 实体名称 "实体内容" >
引用方式:%实体名称;
。
例1,
<!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址">
<!ELEMENT 个人信息 (%TAG_NAMES; | 生日)>
<!ELEMENT 客户信息 (%TAG_NAMES; | 公司名)>
以上dtd文件相当于:
<!ENTITY % TAG_NAMES "姓名 | EMAIL | 电话 | 地址">
<!ELEMENT 个人信息 (姓名 | EMAIL | 电话 | 地址 | 生日)>
<!ELEMENT 客户信息 (姓名 | EMAIL | 电话 | 地址 | 公司名)>
例2,
<!ENTITY % common.attributes
"id ID #IMPLIED
account CDATA #REQUIRED"
>
...
<!ATTLIST purchaseOrder %common.attributes;>
<!ATTLIST item %common.attributes;>
以上dtd文件相当于:
<!ENTITY % common.attributes
"id ID #IMPLIED
account CDATA #REQUIRED"
>
...
<!ATTLIST purchaseOrder id ID #IMPLIED account CDATA #REQUIRED>
<!ATTLIST item id ID #IMPLIED account CDATA #REQUIRED>
根据以下产品目录DTD编写一个xml文档。
产品目录DTD:
<!DOCTYPE CATALOG [
<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "jd@jd-tools.com">
<!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>
<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte"
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>
<!ELEMENT NOTES (#PCDATA)>
]>
在CATALOG.xml文件内编写DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE CATALOG [
<!ENTITY AUTHOR "John Doe">
<!ENTITY COMPANY "JD Power Tools, Inc.">
<!ENTITY EMAIL "jd@jd-tools.com">
<!ELEMENT CATALOG (PRODUCT+)>
<!ELEMENT PRODUCT
(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>
<!ATTLIST PRODUCT
NAME CDATA #IMPLIED
CATEGORY (HandTool|Table|Shop-Professional) "HandTool"
PARTNUM CDATA #IMPLIED
PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago"
INVENTORY (InStock|Backordered|Discontinued) "InStock">
<!ELEMENT SPECIFICATIONS (#PCDATA)>
<!ATTLIST SPECIFICATIONS
WEIGHT CDATA #IMPLIED
POWER CDATA #IMPLIED>
<!ELEMENT OPTIONS (#PCDATA)>
<!ATTLIST OPTIONS
FINISH (Metal|Polished|Matte) "Matte"
ADAPTER (Included|Optional|NotApplicable) "Included"
CASE (HardShell|Soft|NotApplicable) "HardShell">
<!ELEMENT PRICE (#PCDATA)>
<!ATTLIST PRICE
MSRP CDATA #IMPLIED
WHOLESALE CDATA #IMPLIED
STREET CDATA #IMPLIED
SHIPPING CDATA #IMPLIED>
<!ELEMENT NOTES (#PCDATA)>
]>
<CATALOG>
<PRODUCT>
<SPECIFICATIONS>aaaaa</SPECIFICATIONS>
<OPTIONS>ccccc</OPTIONS>
<PRICE>ddddd</PRICE>
<NOTES>bbbbb</NOTES>
</PRODUCT>
</CATALOG>