解析xml文件
DOM解析–>基于面向对象的方式:好理解
工具:dom4j-1.6.1-jar
DOM解析就是通过读取xml文件获取节点对象,通过节点对象更改标签的文本或属性。
步骤:
1.写好指定的xml文件
2.创建xml解析对象 SAXReader saxReader=new SAXReader();
3.利用解析器对象的read(url目录资源的地址/绝对地址)
- 绝对路径
Document document=saxReader.read(url);
- 读取maven工程的classes下面的资源文件:获取当前类字节码文件对象
Document document=saxReader.read(当前类.class.getClassLoader().getResource("XXX.xml"));
4.返回一个document对象–>解析的过程中通过xml中的解析器形成dom树
DOM解析:由SAXReaer解析器,内置了一个解析引擎,遇到第一个标签,则将第一个标签作为根节点rootElement,后面解析标签的标签都开始进行排列,作为它子元素进行排列
解析的内容:标签->解析为接口Element 属性->解析为接口Attribute 文本->解析为接口Text
dom4j中获得标签对象的方法:
1.创建解析器对象SAXReader reader =new SAXReader();
2.加载资源文件Document doc=reader.read("url");
3.基本API:获取根节点对象:getRootElement()
获取一个普通标签之前,必须获得其父标签:Element conList=doc.getRootElement();
获取标签名称:conList.getName();
获取第一个子标签对象:conList.element(“标签名”);
获取同名的所有子节点对象(返回的是集合):conList.elements("标签名称");
获取当前根节点下的所有子节点conList.elements();
dom4j中获得属性的方法:
获取属性的前提是获取所在标签对象
获得属性的两种方法:
1.标签对象.attributeValue("属性名称");
返回值为String
2.标签对象.attribute(“属性名称”);
返回值为Attribute类型
- attribute对象.getValue()
dom4j中获得文本的方法:
两种方法:
1.标签对象.getText();
2.父标签对象.elementText(“子节点名称”);
XML中的空格换行是文本内容,会被解析出来
读取完xml文件后将每一个标签封装为对象进行遍历
步骤:1.创建LIst集合对象
2.使用dom4j解析xml文件得到Document对象
3.document对象获取所有同名的子节点列表放入节点集合
4.遍历集合,获取到每一个标签,封装到标签集合
5.遍历集合,输出到打印台
package www.github.sweeeeeet.web_xml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.ArrayList;
import java.util.List;
/**
* Author:sweet
* Created:2019/4/17
*/
public class Contact {
private String id;
private String name;
private String gender;
private String phone;
private String address;
private String email;
public Contact() {
this.id = id;
this.name = name;
this.gender = gender;
this.phone = phone;
this.address = address;
this.email = email;
}
@Override
public String toString() {
return "Contact{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
", email='" + email + '\'' +
'}';
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public static List<Contact> getContactXML() throws DocumentException {
/*
* 获取文本:先获取标签对象,再获取文本{
* 1.父标签对象.elementText()
* 2.标签对象.getText();
* */
//读取xml文件-->List<Concat>
Document doc= new SAXReader()
.read(Contact.class.getClassLoader().getResource("concat.xml"));
//创建List集合
List<Contact> list=new ArrayList<Contact>();
//获取当前所有同名的contact 标签
List<Element> conList=doc.getRootElement().elements("contact");
for(Element e:conList){
Contact contact=new Contact();
contact.setId(e.attributeValue("id"));
contact.setName(e.elementText("name"));
contact.setEmail(e.elementText("email"));
contact.setPhone(e.elementText("phone"));
contact.setGender(e.elementText("gender"));
contact.setAddress(e.elementText("address"));
list.add(contact);
}
//遍历List集合
for(Contact contact:list){
System.out.println(contact);
}
return list;
}
public static void main(String[] args) {
try {
getContactXML();
} catch (Exception e) {
e.printStackTrace();
}
}
}
dom4j对XML操作的API
解析XML文件获取document对象:Document doc= new SAXReader() .read(Contact.class.getClassLoader().getResource("concat.xml"));
输出到文件:
//添加到D盘
//创建输出流对象
OutputStream outputStream=new FileOutputStream(
new File("D:\\Test\\contact.xml"));
/*
* createPrettyPrint:优雅文件格式,有空格
* createCompactFormat():紧凑格式,用于部署上线
* */
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
//创建输出对象,传递流对象和输出格式
XMLWriter writer=new XMLWriter(outputStream,format);
writer.write(document);
writer.close();
增删改XML文件
1.获取document对象
2.调用API进行修改
添加一个空文档,获得一个文档对象:Document document=DocumentHelper.createDocument();
添加根节点(添加的第一个节点就是根节点): Element root= document.addElement("根节点名称");
添加标签对象:根节点对象.addElement("标签名");
添加文本内容:标签对象.addText("文本内容");
修改标签属性:
-
1.通过直接修改的方法
1)通过父标签获取子标签对象(若有则获取,没有则创建):Element ele=document对象.getRootElement().element("标签名");
2)通过标签对象获取属性对象:Attributr attr=父标签对象.attribute("属性名");
3)通过属性对象修改属性值:属性对象.setValue("属性值");
-
2.通过添加属性的方法
添加属性值(如有则覆盖其属性的属性值):标签对象.addAttribute("属性",“属性值”);
修改文本内容:
1)获取标签对象Element ele=document对象.getRootElement().element("标签名");
2)修改文本内容:标签对象.setText("文本内容");
通过根节点删除指定标签:
- 1.detach()方法
1)通过根节点获取标签对象:Element ele=文档对象.getRootElement().element("标签名");
2)通过标签对象自删:标签对象.detach();
- remove()方法
1)获取父标签对象:Element ele=当前标签对象.getParent();
2)删除子节点对象:父标签对象.remove(指定标签对象);
dom4j的弊端:一次性加载文本(可能会导致OOM(大量记载图片/电商网站))
xpath解析
使用dom4j传统方式删除标签,太过复杂耗时;使用xpath解析XML文件,可以快速定位标签位置。
需要在maven中导入jaxen依赖包
<dependencies>
<dependency>
<!--提供Xpath表达式,快速定位标签-->
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
<type>bundle</type>
</dependency>
</dependencies>
Xpath常用语法:
/:表示绝对路径;在xml中,/在标签名的前面,表示选中当前标签/concat-list:定位到根节点
/在标签名的中间,表示选中当前标签的子节点。/concat-list/concat选中字节点标签concat
//:不分层级关系,定位所有层级标签//concat 不分层级关系选中所有的concat
*:表示通配符/concat-list/*选中caoncat-list标签下的所有子节点(不包括孙节点)
[]:进一步定位元素
@:定位属性@属性名称
=:确定属性值或文本值[@id='001']确定id=001的标签
and 逻辑与
text()=’’:定位xxx的文本内容
API接口:
Node node=selectSingleNode(表达式)
Lise node=selectSingleNodes(表达式);