基础
xml的作用
特点
- 平台无关性(Windows、Linux),的语言
- 90%的语言都支持xml
- xml具有自我描述性(内容自定义)
语法规则(文档声明:<?xml version = "1.0" encoding="UTF-8"?>)
- xml文件中必须要有根元素(根元素只能有一个)
- xml元素必须有开必有合
- xml元素对大小写敏感
- xml元素必须正确地嵌套
- xml元素的属性必须加引号(单引、双引都可)
与HTML的区别
- HTML文件中,所有的元素(标签)都是官方定义好的,我们直接引用即可
- xml文件中,所有元素自定义
xml注释
与HTML一致,为:
<!-- 注释内容 -->
CDATA区
[CDATA[内容]]
内容中可能有需要转义的字符(特殊符号) 需要使用CDATA区域,忽略其本性,变成普通的字符串
DTD文件应用( Document Type Definition 文档类型定义)
文档定义格式
<ELEMENT 根元素(根元素里面的子元素*个数)>
<ELEMENT 子元素(子元素里面的元素) (元素与元素之间用,分隔)
<ELEMENT 子元素的子元素(数据类型) (#PCDATA为字符串类型,)
文档引入xml中(也可以从网站中引入)
<!DOCTYPE 根元素 SYSTEM ""DTD文件路径>
目的
规范xml中的格式
DTD与xml的关系
类型与实例(类似于类与对象的关系)
XSD文件(xml结构定义 XML Schemas Definition)
描述
TDT的替代品,但是比TDT高级
Spring配置文件使用较多
优点
- 基于xml没有专门的语法,和xml一样地解析和处理
- 支持一系列的数据类型
解析xml
解析方式(前两种为基础方法,官方提供,与平台无关的解析方式,后两种属于扩展方法,在基础方法之上扩展出来的,只适用于java平台)
DOM解析
原理
把文档中所有的元素按照其出现的层次关系,在内存中构造出树形结构
优点
可以遍历和修改节点的内容
缺点
内存压力较大,解析较慢(在内存中构造树形结构)
SAX解析
原理
逐行扫描,边扫描边解析
优点
一种更快、更有效的方法
缺点
不能修改节点内容,不能确定节点之间的关系
DOM解析(少)
原理
仅适用具体的类,而不用接口
缺点
不灵活(只使用类,不使用接口)
DOM4J解析(重点 需要先搭建环境)
原理
是JDOM的一种智能分支,合并了许多超出基本xml文档的功能
优点
缺点
使用示例
著名的底层框架hibernate就是使用DOM4J来解析的
解析方式性能排序
DOM4J性能最高,其次是SAX,DOM和JDOM表现不好(解析10Mb大小的xmL文件就内存溢出了)
使用dom4j解析xml文件
容易出现的错误
- 文件位置错误,xml 要放置于src目录下
- 类型引用错误
使用dom4j解析xml文件的流程
- 将xml文件加载到jvm中,形成数据流
InputStream is = xmlUsage.class.getClassLoader().getResourceAsStream("text.xml");
- 创建解析对象
SAXReader sr = new SAXReader();
- 获得整个文档对象,整个xml文件,将数据流转换成一个对象(文档对象)
Document dm = sr.read(is);
- 获得根元素
Element root = dm.getRootElement();
- 获取根元素下的所有子元素
List<Element> list1 = root.elements();// 读取的节点
list.forEach(s->System.out.println(s));
//org.dom4j.tree.DefaultElement@1055e4af [Element: <student attributes: []/>]
- 获取子节点的子节点
for(Element e1:list1) {
List<Element> list2 = e1.elements();
for(Element e2:list2) {
System.out.println(e2.getName()+":"+e2.getData());
}
}
- 获取属性
for(Element e1:list1) {
Attribute type = e1.attribute("type");
System.out.println(type.getValue());
Attribute color = e1.attribute("color");
System.out.println(color.getValue());
}
- xml添加元素,创建节点(在内存中创建,没有写入)
Element student = root.addElement("student");
- 在student中添加id age name元素
Element id = student.addElement("id");
Element name = student.addElement("name");
Element age = student.addElement("age");
- 设置文本内容
id.setText("5");
name.setText("wangWu");
age.setText("16");
- 写入文件(使用xml文件写入的对象,XMLWriter),设置完后并没有写到xml文件中,因为没有IO流写入
XMLWriter xw = new XMLWriter(new FileOutputStream(new File("C:\\Java\\JavaDemo\\xmlExperiment\\src\\text2.xml")),new OutputFormat("\t",true,"UTF-8"));
//OutputFormat为格式:里面参数为,缩进,是否换行,编码格式
- 将整个文档对象写入到文档中
xw.write(dm)
- 关闭资源
xw.close();
XPath
概述
xPath:(xml文件 path路径)
一门在xml文档中快速查找信息的方式
因为单纯地使用dom4j访问节点时,需要一层一层地处理,有了XPath,访问层级的节点就简单了
使用XPath需要引包 jaxen.jar
使用(常用方法及使用技巧)
- 将xml文件加载到jvm中,形成数据流
InputStream is = xmlUsage.class.getClassLoader().getResourceAsStream("text.xml");
- 创建解析对象
SAXReader sr = new SAXReader();
- 获得整个文档对象,整个xml文件,将数据流转换成一个对象(文档对象)
Document dm = sr.read(is);
- 获得根元素
Element root = dm.getRootElement();
- 获取某个名称所有元素节点,使用selectNodes方法
形式:
List<Node> list = root.selectNodes("元素节点名");
list.forEach(s -> System.out.println(s));
实例(获取所有student元素节点):
List<Node> list = root.selectNodes("student");
list.forEach(s -> System.out.println(s));
- 获取指定目标的节点的内容
形式:
List<Node> list = root.selectNodes("元素节点/子元素节点");
list.forEach(s-> System.out.println(s.getText()));
实例(获取student元素节点下的name元素节点):
List<Node> list = root.selectNodes("student/name");
list.forEach(s-> System.out.println(s.getText()));
- 获取指定节点的内容,忽略层级和位置
形式:
List<Node> list = root.selectNodes("//子元素节点");
list.forEach(s-> System.out.println(s.getText()));
实例(获取所有子元素节点下的name节点):
List<Node> list = root.selectNodes("//name");
list.forEach(s-> System.out.println(s.getText()));
- 获的根元素第一个节点的内容
List<Node> list = root.selectNodes("student[1]");
list.forEach(s-> System.out.println(s));
- 获的根元素倒数第二个节点的元素的某个子节点的值 last()表示最后一个
List<Node> list = root.selectNodes("student[last()-1]/name");
list.forEach(s-> System.out.println(s.getText()));
- 获取所有带有特定属性的元素节点
形式:
List<Node> list = root.selectNodes("元素节点[@属性]/指定的子节点");
list.forEach(s-> System.out.println(s.getText()));
实例(带有color属性的student元素节点的子节点name节点):
List<Node> list = root.selectNodes("student[@color]/name");
list.forEach(s-> System.out.println(s.getText()));
- 获取所有带有特定属性且等于某个值的元素节点 注意:属性必须带引号
形式:
List<Node> list = root.selectNodes("元素节点[@属性='属性值']/指定的子节点");
list.forEach(s-> System.out.println(s.getText()));
实例(带有color属性且值为yellow的student元素节点的子节点name节点):
List<Node> list = root.selectNodes("student[@color='yellow']/name");
list.forEach(s-> System.out.println(s.getText()));
- 获取某个属性的值大于指定数值的元素节点
形式:
List<Node> list = root.selectNodes("元素节点[属性>指定值]/指定的子节点");
list.forEach(s-> System.out.println(s.getText()));
实例(带有age属性且age属性值大于18的student元素节点的子节点name节点):
List<Node> list = root.selectNodes("student[age>18]/name");
list.forEach(s-> System.out.println(s.getText()));