XML介绍
X(extensible:可扩展的)M(markup:标记/标签)L(language:语言)
可扩展标记语言
xml语言的作用:
- 存:特殊的文件。(数据库太大,普通文件太慢,所以采用xml文件保存软件中的数据)
- 传:网络上传递数据
- 配置文件 *.properties, *.xml
xml的特点
- 平台无关性,独立的语言
- 90%的语言都支持xml
- xml具有自我描述性(内容自定义)
1)html文件中,所有元素(标签)都是官方定义好的,我们直接引用
2)xml文件中,所有元素自定义
创建xml文件
xml的语法规则
- xml文件必须有根元素
- xml元素(标签) 有开必有合(必须有结束标签)
- xml元素对大小写敏感
- xml元素必须正确的嵌套
- xml元素的属性必须加引号(单引号双引号都可以)
CDATA区
在xml中书写特殊符号时,会报错,忽略其本性,变成普通的字符串。
<![CDATA[xxxxx]}>
错误示例:
<xx> 10<5 </xx>
正确示例:
<xx><![CDATA[ 10<5 ]]></xx>
DTD文件
- DTD的英文:Document Type Definition 文档类型定义
- DTD的目的:帮助编写合法代码
- DTD和xml之间的关系
- 类似类和对象的关系
- 类似数据库表和行(一条记录)的关系
XSD文件
- xsd是xml结构定义(XML Schemas Definition)
- xsd是dtd的替代品,比dtd高端
- xsd的代码基于xml,没有专门的语法,和xml一样的解析与处理
- xsd支持一系列的数据类型
学会解析xml
- DOM解析
- SAX解析
- JDOM解析
- DOM4J解析
前两种属于基础方法,是官方提供的与平台无关的解析方式;
后两种属于扩展方法,他们是在基础的方法之上扩展出来的,只是用于Java平台。
DOM解析:
- dom解析的原理:解析xml的时候,把文档中的所有元素按照其出现的层次关系,在内存中构造出树形结构。
- dom的优点就是可以遍历和修改节点的内容
- 缺点是内存压力较大,解析较慢
SAX解析:
- 是一种xml解析的替代方法
- 相比dom方式,sax是一种速度更快,更有效的方法
- 不能修改节点内容
JDOM解析:
- 仅适用具体的类,而不用接口,不灵活
DOM4J解析:
- JDOM的一种智能的分支,合并了许多超出基本xml文档的功能
- 著名的底层框架hibernate就是用dom4j来解析。
dom4j性能最高,其次是SAX,dom和jdom表现不好(解析10M小的xml文件,就内存溢出了。) - DOM4J解析,需要引包
public class Test1{
/**
* xml文件要放在src下
*/
public static void main(String[] args) throws Exception{
//1.加载xml文件到jvm中,形成数据流
InputStream is = Test1.class.getClassLoader().getResourceAsStream("test.xml");
//2. 创建解析对象
SAXReader sax = new SAXReader();
//3. 获得文档对象(整个xml文件)[将数据流转化成document对象]
Document doc = sax.read(is);
//4. 获得根元素
Element root = doc.getRootElement();
//5. 获得根元素下的所有子元素
List<Element> list = root.elements();
System.out.println(list.size());
list.forEach(s -> System.out.println(s));
//遍历节点
// for(Element e1 : list){
// List<Element> list2 = e1.elements();
// for(Element e2 : list2){
// System.out.println(e2.getName() + ":" + e2.getData());
}
}
//获取元素的属性值
for(Element e1: list){
Attribute type = e1.attribute("type");
System.out.println(type.getValue());
}
}
}
public class Test2{
/**
* xml文件要放在src下
*/
public static void main(String[] args) throws Exception{
//1.加载xml文件到jvm中,形成数据流
InputStream is = Test2.class.getClassLoader().getResourceAsStream("test2.xml");
//2. 创建解析对象
SAXReader sax = new SAXReader();
//3. 获得文档对象(整个xml文件)[将数据流转化成document对象]
Document doc = sax.read(is);
//4. 获得根元素
Element root = doc.getRootElement();
//5. 创建元素(节点)
Element student = root.addElement("staudent");
Element id = student.addElement("id");
id.setText("3");
Element name= student.addElement("name");
name.setText("curry");
Element age= student.addElement("age");
age.setText("30");
//写入xml文件中
FileOutputStream out = new FileOutputStream(new File("D:/aa.xml"));
OutputFormat format = new OutputFormat("\t",true,"UTF-8")
XMLWriter xw = new XMLWriter(out, format);
//将整个文档对象写入到文件中
xw.write(doc);
xw.close();
}
}
Xpath
xml文件path路径
- xpath是一门在xml文档中快速查找信息的方式
- 单纯的使用dom4j访问节点时,需要一层一层的处理,如果有 了xpath,访问层级的节点就简单了
- 使用xpath需要引包:jaxen-1.1-beta-7.jar
//test3.xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1" type="a">
<name>a</name>
<age>11</age>
</student>
<student id="2" type="b">
<name>b</name>
<age>12</age>
</student>
<student id="3" type="c">
<name>c</name>
<age>13</age>
</student>
<beast id="4" type="d">
<name>d</name>
<age>14</age>
</beast>
<beast id="5" type="e">
<name>e</name>
<age>15</age>
</beast>
</students>
public class Test3{
/**
* xml文件要放在src下
*/
public static void main(String[] args) throws Exception{
//1.加载xml文件到jvm中,形成数据流
InputStream is = Test3.class.getClassLoader().getResourceAsStream("test3.xml");
//2. 创建解析对象
SAXReader sax = new SAXReader();
//3. 获得文档对象(整个xml文件)[将数据流转化成document对象]
Document doc = sax.read(is);
//4. 获得根元素
Element root = doc.getRootElement();
//5. 获得所有学生
List<Element> list1 = root.selectNodes("student");
list1.forEach(s -> System.out.println(s));
//获得所有学生的名字
List<Element> list2 = root.selectNodes("student/name");
list2.forEach(s -> System.out.println(s.getData()));
//获得所有的名字,忽略层级和位置
List<Element> list3 = root.selectNodes("//name");
list3.forEach(s -> System.out.println(s.getData()));
//获得前两个学生名
List<Element> list4 = root.selectNodes("student[position()<3]/name");
list4.forEach(s -> System.out.println(s.getData()));
//获得所有带有type属性的学生名
List<Element> list5 = root.selectNodes("student[@type]/name");
list5.forEach(s -> System.out.println(s.getData()));
//获得所有type属性=c的学生名
List<Element> list6 = root.selectNodes("student[@type='cc']/name");
list6.forEach(s -> System.out.println(s.getData()));
//获得所有年龄超过20岁的学生名
List<Element> list7 = root.selectNodes("student[age>20]/name");
list7.forEach(s -> System.out.println(s.getData()));
}
}