1、XML简介
XML是 eXtensible Markup Language(可扩展标记语言)的缩写,是 SGML(标准通用化标记语言)的一个子集,用于提供数据描述格式,适用于不同应用程序间的数据交换,而且这种交换不以预先定义的一组数据结构为前提,增强了可扩展性。
1.2 XML文档结构
XML是一套定义语义标记的规则,同时也是用来定义其他标识语言的元标识语言。下面是一个简单的XML文档的结构。
<?xml version="1.0" encoding="GBK"?> <!--说明是XML文档,并指定XML文档的版本和编码-->
<users> <!--定义XML文档的根元素-->
<descript>用户信息</descript> <!--定义XML文档元素-->
<create_time>创建于2019年10月27日</create_time>
<user id="1">
<blog_url>;
</user>
<user id="2">
<blog_url>;
</user>
</users>
在XML文档的第一行通常是XML声明,用于说明这是一个XML文档。XML文档的声明并不是必需的,但通常建议为XML文档添加XML声明。XML声明的语法格式如下:
<?xml version="version" encoding="value" standalone="value"?>
参数说明:
参数 | 说明 |
version | 用于指定遵守XML规范的版本号。在XML声明中必须包含version属性,该属性必须放在XML声明中其它属性之前。 |
encoding | 用于指定XML文档中字符使用的编码集。通用的编码集为GBK或GB2312(简体中文)、BIG5(繁体中文)、ISO-8859-1(西欧字符)和UTF-8(通用的国际编码)。 |
standalone | 用于指定该XML文档是否和一个外部文档嵌套使用。取值为yes或no,设置属性值为yes,说明是一个独立的XML文档,与外部文件无关联;设置属性值为no,说明XML文档不独立。 |
2、dom4j概述
2.1 dom4j简介
dom4j是sourceforge.net上的一个Java开源项目,主要用于操作XML文档,如创建XML文档和解析XML文档。dom4j应用于Java平台,采用了Java集合框架并完全支持DOM、SAX和JAXP,是一种适合Java程序员使用的Java XML解析器。它具有性能优异、功能强大和易于使用等特点。目前,越来越多的Java软件都在使用dom4j来读写XML。
2.2 dom4j的下载
在使用dom4j解析XML文档时,需要先下载dom4j.jar和jaxen.jar。
将下载后的jar文件引用到项目中。
pom.xml文件的配置:
<!-- 使用dom4j操作XML文档 -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
3、使用dom4j操作XML文档
3.1 创建XML文档
dom4j组件的一个最重要的功能就是创建XML文档,通过该组件可以很方便地创建XML文档。
【示例】使用dom4j创建XML文档。
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 创建XML文档
* @author pan_junbiao
**/
public class CreateXML
{
private static String _path = System.getProperty("user.dir") + "/XML/user.xml"; //XML文档路径
/**
* 创建用户信息XML文档
* @param userList 用户列表
*/
public static boolean createUserXml(List<UserInfo> userList)
{
boolean result = false;
try
{
// 创建文件对象
File file = new File(_path);
//判断文件是否存在,如果不存在,则创建该文件夹
if (!file.exists())
{
//先得到文件的上级目录,并创建上级目录
file.getParentFile().mkdir();
}
Document document = DocumentHelper.createDocument(); //创建XML文档对象
Element rootElement = DocumentHelper.createElement("users"); //创建普通节点
document.setRootElement(rootElement); //将该节点设置为根节点
for (UserInfo user : userList)
{
//添加子节点
Element userElement = rootElement.addElement("user"); //新增子节点
userElement.addAttribute("id", String.valueOf(user.getId())); //添加属性
Element userElement_userName = userElement.addElement("user_name"); //添加子节点
userElement_userName.setText(user.getUserName()); //设置子节点内容
Element userElement_blogUrl = userElement.addElement("blog_url"); //添加子节点
userElement_blogUrl.setText(user.getBlogUrl()); //设置子节点内容
Element userElement_remark = userElement.addElement("remark"); //添加子节点
userElement_remark.addCDATA(user.getRemark()); //设置节点内容为 CDATA 段
}
//创建 OutputFormat 对象
OutputFormat format = OutputFormat.createPrettyPrint(); //格式化为缩进方式
format.setEncoding("GBK"); //设置写入流编码
//保存文件
XMLWriter writer = new XMLWriter(new FileWriter(_path), format);
writer.write(document);
//释放资源
writer.close();
document.clearContent();
//设置执行成功
result = true;
}
catch (IOException e)
{
e.printStackTrace();
}
return result;
}
/**
* 调用:执行方法
*/
public static void main(String[] args)
{
//创建用户信息,用于保存到XML文件中
UserInfo user1 = new UserInfo();
user1.setId(1);
user1.setUserName("pan_junbiao的博客");
user1.setBlogUrl("");
user1.setRemark("您好,欢迎访问 pan_junbiao的博客!");
UserInfo user2 = new UserInfo();
user2.setId(2);
user2.setUserName("pan_junbiao的博客_002");
user2.setBlogUrl("");
user2.setRemark("您好,欢迎访问 pan_junbiao的博客!");
List<UserInfo> userList = new ArrayList<UserInfo>();
userList.add(user1);
userList.add(user2);
//创建用户信息XML文档
UserBiz userBiz = new UserBizImpl();
boolean result = createUserXml(userList);
//显示执行结果
if(result)
{
System.out.println("创建XML文档成功");
}
else
{
System.out.println("创建XML文档失败");
}
}
}
程序执行后,将生成XML目录和user.xml文档,如下:
<?xml version="1.0" encoding="GBK"?>
<users>
<user id="1">
<user_name>pan_junbiao的博客</user_name>
<blog_url>;
<remark><![CDATA[您好,欢迎访问 pan_junbiao的博客!]]></remark>
</user>
<user id="2">
<user_name>pan_junbiao的博客_002</user_name>
<blog_url>;
<remark><![CDATA[您好,欢迎访问 pan_junbiao的博客!]]></remark>
</user>
</users>
3.2 XML文档的增删改查
【示例】使用dom4j实现XML文档的增删改查。
(1)创建UserInfo.java(用户信息类)。
/**
* 用户信息类
* @author pan_junbiao
**/
public class UserInfo
{
private int id; //用户ID
private String userName; //用户名称
private String blogUrl; //博客地址
private String remark; //备注
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getBlogUrl()
{
return blogUrl;
}
public void setBlogUrl(String blogUrl)
{
this.blogUrl = blogUrl;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
}
(2)创建UserParam.java(用户参数类)。
/**
* 用户参数类
* @author pan_junbiao
**/
public class UserParam
{
private int id; //用户ID
private String userName; //用户名称
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
}
(3)创建UserBiz.java(用户信息业务逻辑接口)。
import java.util.List;
/**
* 用户信息业务逻辑接口
* @author pan_junbiao
**/
public interface UserBiz
{
/**
* 获取用户列表
*
* @param param 用户查询参数类
* @return 用户列表
*/
public List<UserInfo> getUserList(UserParam param);
/**
* 根据用户ID,获取用户信息
* @param userId 用户ID
* @return 用户信息
*/
public UserInfo getUserDetail(int userId);
/**
* 新增用户信息
*/
public boolean addUser(UserInfo userInfo);
/**
* 修改用户信息
*/
public boolean updateUser(UserInfo userInfo);
/**
* 删除用户信息
*/
public boolean deleteUser(int userId);
}
(4)创建UserBizImpl.java(用户信息业务逻辑类),并实现UserBiz.java接口。
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 用户信息业务逻辑类
* @author pan_junbiao
**/
public class UserBizImpl implements UserBiz
{
private String _path = System.getProperty("user.dir") + "/XML/user.xml"; //XML文档路径
/**
* 获取用户列表
*
* @param param 用户查询参数类
* @return 用户列表
*/
@Override
public List<UserInfo> getUserList(UserParam param)
{
List<UserInfo> result = null;
try
{
String xPath = "/users/user"; //创建xPath表达式
//根据用户ID查询
if (param.getId() > 0)
{
xPath = String.format("/users/user[@id='%d']", param.getId());
}
//根据用户名称查询
else if (param.getUserName() != null && param.getUserName().length() > 0)
{
xPath = String.format("/users/user[user_name='%s']", param.getUserName());
}
SAXReader reader = new SAXReader(); //实例化 SAXReader 对象
Document document = reader.read(_path); //获取XML文件对应的XML文档对象
List<Node> nodes = document.selectNodes(xPath);
if (nodes != null && nodes.size() > 0)
{
result = new ArrayList<UserInfo>();
for (Node node : nodes)
{
Element element = (Element)node;
UserInfo userInfo = new UserInfo();
userInfo.setId(Integer.parseInt(element.attributeValue("id"))); //获取节点属性
userInfo.setUserName(element.element("user_name").getText()); //获取子节点内容
userInfo.setBlogUrl(element.element("blog_url").getText());
userInfo.setRemark(element.element("remark").getText());
result.add(userInfo);
}
}
}
catch (DocumentException e)
{
e.printStackTrace();
}
return result;
}
/**
* 根据用户ID,获取用户信息
* @param userId 用户ID
* @return 用户信息
*/
@Override
public UserInfo getUserDetail(int userId)
{
UserInfo result = null;
try
{
if(userId<=0)
{
return null;
}
SAXReader reader = new SAXReader(); //实例化 SAXReader 对象
Document document = reader.read(_path); //获取XML文件对应的XML文档对象
Element rootElement = document.getRootElement(); //获取根节点
// 获取对应userId参数的节点信息
Element element = (Element)rootElement.selectSingleNode("/users/user[@id='"+ userId +"']");
if(element!=null)
{
result = new UserInfo();
result.setId(Integer.parseInt(element.attributeValue("id"))); //获取节点属性
result.setUserName(element.element("user_name").getText()); //获取子节点内容
result.setBlogUrl(element.element("blog_url").getText());
result.setRemark(element.element("remark").getText());
}
}
catch (DocumentException e)
{
e.printStackTrace();
}
return result;
}
/**
* 新增用户信息
*/
@Override
public boolean addUser(UserInfo userInfo)
{
boolean result = false;
try
{
SAXReader reader = new SAXReader(); //实例化 SAXReader 对象
Document document = reader.read(_path); //获取XML文件对应的XML文档对象
Element rootElement = document.getRootElement(); //获取根节点
//创建新子节点
Element userElement = rootElement.addElement("user");
userElement.addAttribute("id", String.valueOf(userInfo.getId())); //添加属性
Element userElement_userName = userElement.addElement("user_name"); //添加子节点
userElement_userName.setText(userInfo.getUserName()); //设置子节点内容
Element userElement_blogUrl = userElement.addElement("blog_url"); //添加子节点
userElement_blogUrl.setText(userInfo.getBlogUrl()); //设置子节点内容
Element userElement_remark = userElement.addElement("remark"); //添加子节点
userElement_remark.addCDATA(userInfo.getRemark()); //设置节点内容为 CDATA 段
//创建 OutputFormat 对象
OutputFormat format = OutputFormat.createPrettyPrint(); //格式化为缩进方式
format.setEncoding("GBK"); //设置写入流编码
//保存文件
XMLWriter writer = new XMLWriter(new FileWriter(_path), format);
writer.write(document);
//释放资源
writer.close();
document.clearContent();
//设置执行成功
result = true;
}
catch (DocumentException de)
{
de.printStackTrace();
}
catch (IOException ie)
{
ie.printStackTrace();
}
return result;
}
/**
* 修改用户信息
*/
@Override
public boolean updateUser(UserInfo userInfo)
{
boolean result = false;
try
{
//先根据用户ID,获取要被修改的用户信息
SAXReader reader = new SAXReader(); //实例化 SAXReader 对象
Document document = reader.read(_path); //获取XML文件对应的XML文档对象
Element rootElement = document.getRootElement(); //获取根节点
// 获取对应userId参数的节点信息
Element item = (Element)rootElement.selectSingleNode("/users/user[@id='"+ userInfo.getId() +"']");
if(item==null)
{
return false;
}
else
{
item.element("user_name").setText(userInfo.getUserName());
item.element("blog_url").setText(userInfo.getBlogUrl());
item.element("remark").setText("");
item.element("remark").addCDATA(userInfo.getRemark());
//创建 OutputFormat 对象
OutputFormat format = OutputFormat.createPrettyPrint(); //格式化为缩进方式
format.setEncoding("GBK"); //设置写入流编码
//保存文件
XMLWriter writer = new XMLWriter(new FileWriter(_path), format);
writer.write(document);
//释放资源
writer.close();
document.clearContent();
//设置执行成功
result = true;
}
}
catch (DocumentException de)
{
de.printStackTrace();
}
catch (IOException ie)
{
ie.printStackTrace();
}
return result;
}
/**
* 删除用户信息
*/
@Override
public boolean deleteUser(int userId)
{
boolean result = false;
try
{
//先根据用户ID,获取要被修改的用户信息
SAXReader reader = new SAXReader(); //实例化 SAXReader 对象
Document document = reader.read(_path); //获取XML文件对应的XML文档对象
Element rootElement = document.getRootElement(); //获取根节点
// 获取对应userId参数的节点信息
Element item = (Element)rootElement.selectSingleNode("/users/user[@id='"+ userId +"']");
if(item==null)
{
return false;
}
else
{
//删除节点
rootElement.remove(item);
//创建 OutputFormat 对象
OutputFormat format = OutputFormat.createPrettyPrint(); //格式化为缩进方式
format.setEncoding("GBK"); //设置写入流编码
//保存文件
XMLWriter writer = new XMLWriter(new FileWriter(_path), format);
writer.write(document);
//释放资源
writer.close();
document.clearContent();
//设置执行成功
result = true;
}
}
catch (DocumentException de)
{
de.printStackTrace();
}
catch (IOException ie)
{
ie.printStackTrace();
}
return result;
}
}
执行方法:
(1)调用获取用户列表方法。
/**
* 执行方法:获取用户列表
* @author pan_junbiao
*/
public static void getUserListTest()
{
//创建查询参数类
UserParam userParam = new UserParam();
//userParam.setId(1); //根据用户ID查询
//userParam.setUserName("pan_junbiao的博客"); //根据用户名称查询
//获取用户列表
UserBiz userBiz = new UserBizImpl();
List<UserInfo> userInfoList = userBiz.getUserList(userParam);
//显示执行结果
if(userInfoList!=null && userInfoList.size()>0)
{
System.out.println("查询数据共:" + userInfoList.size()+ "条");
for (UserInfo user:userInfoList)
{
System.out.println("用户ID:" + user.getId());
System.out.println("用户名称:" + user.getUserName());
System.out.println("博客地址:" + user.getBlogUrl());
System.out.println("备注信息:" + user.getRemark());
System.out.println("============================================");
}
}
else
{
System.out.println("无数据");
}
}
执行结果:
(2)调用根据用户ID,获取用户信息方法。
/**
* 执行方法:根据用户ID,获取用户信息
* @author pan_junbiao
*/
public static void getUserDetailTest()
{
//获取用户信息
UserBiz userBiz = new UserBizImpl();
UserInfo userInfo = userBiz.getUserDetail(1);
//显示执行结果
if(userInfo!=null)
{
System.out.println("根据用户ID,获取用户信息:");
System.out.println("用户ID:" + userInfo.getId());
System.out.println("用户名称:" + userInfo.getUserName());
System.out.println("博客地址:" + userInfo.getBlogUrl());
System.out.println("备注信息:" + userInfo.getRemark());
}
else
{
System.out.println("无数据");
}
}
执行结果:
(3)调用新增用户信息方法,然后重新查询用户列表信息。
/**
* 执行方法:新增用户信息
* @author pan_junbiao
*/
public static void addUserTest()
{
//创建用户信息
UserInfo user = new UserInfo();
user.setId(3);
user.setUserName("pan_junbiao的博客_003");
user.setBlogUrl("");
user.setRemark("您好,欢迎访问 pan_junbiao的博客!");
//保存到XML文档中
UserBiz userBiz = new UserBizImpl();
boolean reuslt = userBiz.addUser(user);
//获取用户列表
UserParam userParam = new UserParam();
List<UserInfo> userInfoList = userBiz.getUserList(userParam);
//显示执行结果
if (userInfoList != null && userInfoList.size() > 0)
{
System.out.println("执行新增用户信息后,重新查询用户列表:");
System.out.println("查询数据共:" + userInfoList.size() + "条");
for (UserInfo item : userInfoList)
{
System.out.println("用户ID:" + item.getId());
System.out.println("用户名称:" + item.getUserName());
System.out.println("博客地址:" + item.getBlogUrl());
System.out.println("备注信息:" + item.getRemark());
System.out.println("============================================");
}
}
}
执行结果:
(4)调用修改用户信息方法,然后重新查询用户列表信息。
/**
* 执行方法:修改用户信息
* @author pan_junbiao
*/
public static void updateUserTest()
{
//修改userId为3的用户信息
UserInfo user = new UserInfo();
user.setId(3);
user.setUserName("pan_junbiao的博客_003(1)");
user.setBlogUrl("(2)");
user.setRemark("您好,欢迎访问 pan_junbiao的博客!(3)");
//执行修改操作
UserBiz userBiz = new UserBizImpl();
boolean reuslt = userBiz.updateUser(user);
//获取用户列表
UserParam userParam = new UserParam();
List<UserInfo> userInfoList = userBiz.getUserList(userParam);
//显示执行结果
if (userInfoList != null && userInfoList.size() > 0)
{
System.out.println("执行修改用户信息后,重新查询用户列表:");
System.out.println("查询数据共:" + userInfoList.size() + "条");
for (UserInfo item : userInfoList)
{
System.out.println("用户ID:" + item.getId());
System.out.println("用户名称:" + item.getUserName());
System.out.println("博客地址:" + item.getBlogUrl());
System.out.println("备注信息:" + item.getRemark());
System.out.println("============================================");
}
}
}
执行结果:
(5)调用删除用户信息方法,然后重新查询用户列表信息。
/**
* 执行方法:删除用户信息
* @author pan_junbiao
*/
public static void deleteUserTest()
{
//删除userId为3的用户信息
UserBiz userBiz = new UserBizImpl();
boolean reuslt = userBiz.deleteUser(3);
//获取用户列表
UserParam userParam = new UserParam();
List<UserInfo> userInfoList = userBiz.getUserList(userParam);
//显示执行结果
if (userInfoList != null && userInfoList.size() > 0)
{
System.out.println("执行删除用户信息后,重新查询用户列表:");
System.out.println("查询数据共:" + userInfoList.size() + "条");
for (UserInfo item : userInfoList)
{
System.out.println("用户ID:" + item.getId());
System.out.println("用户名称:" + item.getUserName());
System.out.println("博客地址:" + item.getBlogUrl());
System.out.println("备注信息:" + item.getRemark());
System.out.println("============================================");
}
}
}
执行结果: