Java篇-XML书写与解析
一 : XML 简介
XML
(Extensible Markup Language) ,可扩展标记语言,与HTML较为相似.HTML中的元素是固定的,XML的标签是可以用户自定义的. 现在通常用JSON
作为数据间的传输,XML
则作为配置文件.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.example.org/web-app_2_5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>
hello雪芙
</servlet-name>
<servlet-class>
111111
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
hellow雪瑶
</servlet-name>
<url-pattern>
2222
</url-pattern>
</servlet-mapping>
</web-app>
二 : XML语法与结构
文档声明
-
文档声明以
<? xml开头
, 以?>
结束 -
文档声明必须从文档的0行0列位置开始:
也就是说我们编写XML
文件时候必须以左上角为起始点,不能留任何间隔.
元素
- 元素有结构开始标签,元素体,结束标签组成,
<servlet-name> hello雪芙 </servlet-name>
- 元素体 : 元素体可以是元素,也可以说文本,也就是说元素之间是可以嵌套的, 如 :
<world>
<me>
life</me>
</world>
- 空元素 : 空元素只有开始标签,而没有结束标签,但元素必须自己闭合,
<a/>
- 元素命名规范 :
- 区分大小写
- 不能使用空格,冒号.
- 有且只有一个根元素.
属性
- 属性是元素的一部分,必须出现在元素的开始标签中
- 属性的定义格式 : 属性名 = '属性值',其中属性值必须使用单引号或双引号.
- 一个元素中可以有多个属性,但属性名不能相同
- 属性名不能使用空格,冒号等特殊字符,且必须以字母开头
注释
注释与HTML的相同 ,command+/
快捷键, ,注释内容会被解析器忽略!
转义字符
由于很多符号已经被XML 文档结构所使用,所以在元素体或属性值中想要使用这些符号就必须使用转义字符.
字符 | 字符引用(十进制代码) | 字符引用(十六进制代码) | 预定义实体引用 |
---|---|---|---|
< | < | < | < |
> | > | > | > |
" | " | " | " |
' | ' | ' | &apos |
& | & | & | & |
CDATA
当有大量转义字符,或者图省事,可以使用CDTA,不仅能使XML可读性提高,而且很简单.
<?xml version = "1.0"?>
<hellow version = "1" id= "1">
<b>
<![CDATA[
dfsdfsdf
]]>
</b>
</hellow>
在CDATA段中不能包含"]]>",即CDTA段的结束定界符.
三 : XML常见约束
( 一 ) DTD约束
DTD( Document Type Definition)
,文档类型定义,用来约束XML文档,规定XML文档中元素的名称,子元素的名称及顺序,元素属性等.开发中我们几乎不会编写DTD约束文档,都是使用框架提供的DTD约束文档.
常见框架使用DTD约束有 : struts2
,hibernate
等
<!ELEMENT web-app (servlet*,servlet-mapping* , welcome-file-list?) >
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+) >
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>
<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>
<!ATTLIST web-app version CDATA #IMPLIED>
使用DTD文档的方法.
①导入.dtd约束文档,拷贝到相同目录下
②拷贝DTD文档开始处,拷贝需要的文档声明,复制到自己的XML配置文件里.
③根据提示编写XML内容.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version = "1.0">
<servlet>
<servlet-name>
</servlet-name>
<servlet-class>
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
aaa
</servlet-name>
<url-pattern>
</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
</welcome-file>
</welcome-file-list>
</web-app>
XML引入DTD的三种声明方式 :
①内部DTD,在XML文档内部嵌入DTD,只对当前XML有效.
②外部DTD,本地DTD,DTD文档在本地系统上,内部自己项目使用,关键字 : SYSTEM
③外部DTD,公共DTD,DTD文档在网络上,一般都有框架提供关键字 : PUBLIC
( 二 )Schema约束
与DTD一样也是XML的文档约束,相比于DTD,功能更为强大,是DTD替代者,后缀名为xsd
,支持名称空间
常见框架使用schema的有Spring
等
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/web-app_2_5"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://www.example.org/web-app_2_5"
elementFormDefault="qualified">
<xsd:element name="web-app">
<xsd:complexType>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="servlet">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="servlet-name"></xsd:element>
<xsd:element name="servlet-class"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="servlet-mapping">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="servlet-name"></xsd:element>
<xsd:element name="url-pattern" maxOccurs="unbounded"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="welcome-file-list">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="welcome-file" maxOccurs="unbounded"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:attribute name="version" type="double" use="optional"></xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Schema约束使用方式与DTD使用方式一样.
命名空间
如果一个XML文档使用多个Schema文件,多个文件中定义同名元素时,就会出现名字冲突,命名空间就是用来处理元素和属性的名称冲突问题的,与Java中的包是同一用途.
在.xsd文件中
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" ...>
表示自定义schema约束文档引用官方文档作为显示命名空间,如果要使用官方提供的元素或属性,必须使用xsd前缀.
targetNamespace="http://www.example.org/web-app_2_5"
表示给当前自定义约束文档进行起名,提供给xml文档使用
xmlns:tns="http://www.example.org/web-app_2_5"
要是有改schema文件元素,就要在前面加前缀tns
在根据schema文档写的XML文件中
<web-app xmlns="http://www.example.org/web-app_2_5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>
hello雪芙
</servlet-name>
<servlet-class>
111111
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
hellow雪瑶
</servlet-name>
<url-pattern>
2222
</url-pattern>
</servlet-mapping>
</web-app>
<web-app xmlns="http://www.example.org/web-app_2_5"
表示XML文档引用自定义约束文档,作为默认命名空间.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
表示是一个schema实例文档,引入w3c实例文档.
xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
表示确定当前xml使用到的schema文档的位置,名称 与 路径称为出现
四 : XML解析
-
解析方式
① DOM
: 要求解析器把整个XML文档装载到内存,并解析成一个Document对象.
使用DOM解析能使元素与元素之间保留结构关系,故可以进行增删改查操作,但是XML文档过大,可能出现内存溢出现象.
② 'SAX' : 是一种速度更快,更有效的方法,它逐行扫描文档,一边扫描一边解析,并以事件驱动的方式进行具体解析,每执一行,都将处罚对应的事件.
处理速度快,可处理大文件,但是只能读没然后逐行释放资源.
③PULL : Android内置的XML解析方式,类似SAX
-
常见的解析开发包 :
① JAXP : sun公司提供支持DOM和SAX开发包
② jsoup : 一种处理HTML特定解析开发包
③ dom4j : 比较常用的解析开发包,hibernate
底层采用
④ JDom : dom4j兄弟
-
DOM解析原理
XML DOM 与HTML DOM 类似,将整个XML加载到内存,生成DOM树,并获得一个Document对象,通过Document对象就可以对DOM进行操作
-
dom4j API使用
①导入jar包
② XML文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.example.org/web-app_2_5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>
MyServlet1
</servlet-name>
<servlet-class>
com.TianTianBayby.web.servlet1.MyServlet1
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
MyServlet1
</servlet-name>
<url-pattern>
/myServlet1
</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>
MyServlet2
</servlet-name>
<servlet-class>
com.TianTianBayby.web.servlet1.MyServlet2
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
MyServlet2
</servlet-name>
<url-pattern>
/myServlet2
</url-pattern>
</servlet-mapping>
</web-app>
③ dom4j 使用核心类SaxReader
加载xml文档获得Document,
通过Document对象获得文档
public void testMyServlet() throws Exception{
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.使用解析器加载web.xml文件得到document对象
Document document = saxReader.read("src/com/TianTianBayby/web/servlet1/web.xml");
//3.获取根元素节点
Element rootElement = document.getRootElement();
//4.根据元素名称获取子元素节点
Element servletElement = rootElement.element("servlet");
//5.根据元素名称获取servlet-class的文本节点
String servletClass = servletElement.element("servlet-class").getText();
//6.通过类全名获取字节码文件
Class clazz = Class.forName(servletClass.trim());
// //7创建实例对象
IMServlet my = (IMServlet)clazz.newInstance();
my.init();
my.service();
my.destory();
}
}
MyServlet1创建
MyServlet1服务
MyServlet1销毁
-
dom4j 常用方法
① SaxReader对象,
read("..")
加载执行xml文档
② Document对象
getRootElement()
获得根元素
③ Element对象
elements("..")
获得指定名称的所有子元素,可以不指定名称
element("..")
获得指定名称的第一个子元素,可以不指定名称
getName()
获得当前元素的元素名
attributeValue("..")
获得指定属性名的属性值
elementText("..")
获得指定名称子元素的文本值
getText()
获得当前元素的文本内容