XML解析
其实就是获取元素里面的字符数据或者属性数据
解析方式
有很多种,但是常用的有两种
- DOM
- SAX
DOM:document object model 把整个xml全部读到内存中,形成树状结构,整个文档称之为documet对象,属性对应attribute对象,所有的元素节点对应element对象,文本称之为text 对象,以上所有对象都可以称之为Node节点。如果xml特别大,那么将会造成内存溢出,可以对文档进行增删操作。
SAX: Simple API for Xml 基于事件驱动,读取一行,解析一行。不会造成内存溢出,不可以进行增删,只能查询
针对这两种解析方式的API
- jaxp sum公司,比较繁琐
- jdom
- dom4j 使用比较广泛
dom4j基本用法
前提:下载dom4j的包
1.创建SAXReader对象
2.指定解析的xml
3.获取根元素
4.根据根元素获取子元素或者下面的子孙元素
public class MainTest{
public static void main(String[] args){
try{
//1.创建sax读取对象
SAXReader reader = new SAXReader();
//2.指定解析的xml源
Document document = reader.read(new File("xxx"));
//3.得到元素
//根元素
Element rootElement = document.getRootElement();
//获取根元素下面的子元素age
System.out.println(rootElement.element("stu").element("age").getText());
//获取根元素下面的所有子元素
List<Element> elements = rootElement.elements();
//遍历获取子孙元素
for(Element e:elements){
String name = e.element("name").getText();
}
}catch(Exception e){
e.PrintStackTrace();
}
}
}
xpath的用法
dom4j里面支持Xpath的写法
xpath其实是xml的路径语言,支持我们在解析xml的时候,能够快速定位到具体的某一个元素
1.添加jar包依赖
jaxen-1.1-beta-6.jar
2.在查找指定节点的时候,根据xpath语法规则来查找
3.后续的代码与以前的解析代码一样
//根元素
Element rootElement = document.getRootElement();
//要想使用Xpath,还得添加支持的jar 获取的是第一个元素
//获取所有名字为name的元素中的第一个
Element nameElement = (Element)rootElement.selectSingleNode("//name");
System.out.println(nameElement.getText());
//获取文档里面的所有name元素
List<Element> list = rootElement.selectNodes("//name");
//遍历输出text
for(Element e:elements){
System.out.println(e.getText());
}
XML约束
有时候XML需要某些要求,比如说ID唯一,元素只能出现一次等等,这就需要对XML添加XML约束了
约束主要有以下两类:
-
DTD
语法自成一派,早期就出现的,可读性比较差
-
Schema
其实就是一个XML,使用XML语法规则,XML解析器解析起来比较方便,是为了代替DT,但是Schema约束文本内容比DTD的内容还要多,所以目前也没有真正意义上替代DTD
DTD基本用法
DTD的写法
<!-- 一共有四个元素 -->
<!-- stus元素中有stu,但是只有一个 -->
<!-- 元素的个数
+ 一个或多个
* 零个或多个
? 零个或一个
没有 只有一个 -->
<!ELEMENT stus(stu)+>
<!-- stu元素中有name和age,而且name必须在age前面 -->
<!ELEMENT stu(name,age)>
<!-- name元素中是可解析字符文本 -->
<!ELEMENT name(#PCDATA)>
<!-- age元素中是可解析字符文本 -->
<!ELEMENT age(#PCDATA)>
<!-- stu有一个属性id 文本类型 该属性可有可无 -->
<!-- 如果属性是必需的,用#REQUIRED
如果属性是固定的,用#FIXED values
如果要给它设一个默认值,则直接在此位置输入值就行 -->
<!ATTLIST stu id CDATA #IMPLIED>
在xml中引入DTD,有三种途径
1.引入网络中的DTD
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入DTD来约束这个xml -->
<!-- 1.引入网络上的DTD
DOCTYPE:文档类型
stus:根标签名字
PUBLIC:指网络上的DTD
"//UNKNOWN/":DTD名称
"unknown.dtd":网络上的DTD路径-->
<!DOCTYPE stus PBULIC "//UNKNOWN/" "unknown.dtd">
2.第二种,引入本地的DTD
<!-- 2.引入本地的DTD
DOCTYPE:文档类型
stus:根标签名字
SYSTEM:指本地的DTD
"unknown.dtd":本地的DTD路径-->
<!DOCTYPE stus SYSTEM "stus.dtd">
3.第三种,直接在xml内嵌DTD
<!DOCTYPE stus[
<!ELEMENT stus(stu)>
<!ELEMENT stu(name,age)>
<!ELEMENT name(#PCDATA)>
<!ELEMENT age(#PCDATA)>
]>
Schema基本用法
Schema的写法
<?xml version="1.0" encoding="UTF-8">
<!-- xmlns:xml namespeace 名称空间/命名空间
targetNamespeace: 目标名称空间,下面定义的那些元素都与这个名称空间绑定上
elementFormDefault: 元素的格式化情况 -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespeace="http://www.example.org/teacher"
elementFormDefault="qualified">
<!-- 这是一个复杂元素-->
<element name="teachers"></element>
<complexType>
<sequence maxOccurs="unbounded">
<!-- 这是一个复杂元素 数量为无限大-->
<element name="teacher">
<complexType>
<sequence>
<!-- 以下是两个简单元素-->
<element name="name" type="String"></element>
<element name="age" type="int"></element>
<sequence>
</complexType>
</element>
<sequence>
</complexType>
</element>
</schema>
schema的引入
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns:xsi :这里必须是这样的写法,也就是这个值已经固定了
xmlns :这里是名称控,也固定了,写的是schema里面的顶部目标名称空间
xsi:schemaLocation :有两段,前半段是名称空间,也是目标空间的值,后半段是约束文档的路径-->
<teachers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/teacher"
xsi:schemaLocation="http://www.example.org/teacher teacher.xsd"
>
<teacher>
<name>zhangsan</name>
<age>18</age>
</teacher>
<teacher>
<name>lisi</name>
<age>15</age>
</teacher>
</teachers>
名称空间的作用
一个xml可以引用多个schema约束,但是只能引用一个DTD约束
下面是引用多个schema约束的情况
<teachers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bb="http://www.example.org/teacher"
xmlns:aa="http://www.example.org/teacher"
xsi:schemaLocation="http://www.example.org/teacher teacher.xsd"
>
<teacher>
<aa:name>zhangsan</name>
<age>18</age>
</teacher>
<teacher>
<aa:name>lisi</name>
<age>15</age>
</teacher>
</teachers>