XML文件简介
XML文件介绍
- XML(EXtensible Markup Language)是扩展性标记语言。由程序设计编写者自定义实现。
- XML主要是用来以标记文本形式表示一组或多组数据,很多计算机语言都提供对XML文件的解析,使用XML格式传递数据可以实现跨平台跨计算机编程语言
- XML是W3C组织强烈推荐的数据交换格式标准
XML语法规则
- 标准声明 <?xml version="1.0" encoding="UTF-8"?>:版本号和编码方式
- 标签封闭 This is a paragraph
- 这是错误的:标签大小写敏感,一边大写一边小写则为达到标签封闭
- …至少有一个根元类:root为根元素,child为子元素
- xml的属性值必须加引号("或’)
- 实体引用:
<:<
>:>
&:&
&apos:’
":"
- 注释符《!–注释–》(英文符号)
- 在XML中,空格会被保留,属性与数据中有空格,则空格也是属性和数据中的一部分
XML文档的编写
XML元素
- XML中的元素是用<元素名称>与</元素名称>定义在文档中的节点描述
- 元素中可以包含其他子元素、元素属性及普通常量文本
- 名称可以含字母、数字以及其他的字符(建议只使用字母与数字)
- 名称不能以数字或者标点符号开始
- 名称不能以字符xml(或者XML,Xml)开始
- 名称不能包含空格
XML元素属性
- XML中属性是用来描述元素特征的,它必须有名称和值组成,之间用=符号实现赋值,属性值必须使用单引号或者双引号包围
- 特殊情况:
如果属性本身包含双引号,那么有必要使用单引号包围它如:name='George “Shotgun” Ziegler’不建议使用
或者可以使用实体引用
代码示例
<?xml version="1.0" encoding="UTF-8"?>
<!-- 此XML文档用来存储学生信息 -->
<!-- 这是文档的根元素 -->
<students>
<!-- 每个student元素代表一个学生对象 -->
<student ID="001">
<name>张三</name>
<birth>2001-1-1</birth>
<sex>男</sex>
</student>
<student ID="002">
<name>李四</name>
<birth>2001-2-1</birth>
<sex>女</sex>
</student>
<student ID="003">
<name>王五</name>
<birth>2001-3-1</birth>
<sex>男</sex>
</student>
</students>
student对象的子元素起到和属性类似的作用,描述对象的特征,子元素之间的是文本,字符串常量
XML文件的解析
- DOM文档对象模型
- SAX简单的XML API
- JDOM Java文档对象类型
- DOM4J扩展JDOM
JDOM解析XML
JDOM概述
- JDOM是由第三方提供和维护的一组标准的Java实现,用来以Java语言形式解析XML文档;因此它知识和与Java平台语言,JDOM不遵循任何DOM实现标准,它只和Java相关
- JDOM对XML文档实现最为简单的读写操作,JDOM将XML文档中的每个节点(node)称之为Element(元素),并提供对元素上下级元素的获取等实用方法
- JDOM解析XML大体分为两种操作
- 读取目标XML文档并解析,封装成运行时的Java对象进行处理
- 将运行的Java对象以XML文件方式写入硬盘存储
JDOM读取XML文档
流程
- 创建SAXBuilder用来构建加载目标XML文档
- 基于XML路径创建XML文件对象
- 使用SAXBuilder加载XML文件对象
- 利用JDOM相关方法解析XML文档封装为Java对象
获取应用程序类路径
Java程序的输出目录是bin目录,不能从src中获取文件,由于开发者文件路径和用户不同,需要通过获取类路径的方式来获得文件
/**
* 获取类路径的通用方法
* @return String 类路径
*/
public static String getClassPath() {
/*getClassLoader.getResource()获得文件的绝对路径,getPath获取部分路径(省去file:部分)*/
String classPath = Tools.class.getClassLoader().getResource("").getPath().toString();
/*解码,修改编码格式,防止乱码*/
try {
URLDecoder.decode(classPath, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return classPath;
}
代码实现
学生实体类
import java.util.Date;
/***
* 学生实体类,存储学生信息
* @author lenovo
*
*/
public class Students {
private String ID;
private String name;
private Date birth;
private Sex sex;
private enum Sex{
男,
女;
}
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 Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Sex getSex() {
return sex;
}
public void setSex(Character sex) {
this.sex = Sex.valueOf(sex.toString());
}
}
xml文档的解析功能类
/***
* xml文档的解析功能类
* @author lenovo
*
*/
public class JDOMXMLManager {
/*创建需要使用的SAXBuilder和Document对象*/
private static SAXBuilder saxbuilder;//用来构建xml文件
private static Document document;//xml文档对象
/**
* 此方法用来创建一个SAXBuilder对象
*/
private static void newInstanceSAXBuilder() {
if(saxbuilder == null)
saxbuilder = new SAXBuilder();
}
/**
* 将文件的数据封装为Students对象,存储在集合List中返回
* @return List封装学生对象的集合链表
*/
public static List<Students> toStudentsFromXML(String xmlFileName){
List<Students> stuList = new ArrayList<Students>();
/*1.通过方法创建SAXBuilder用来构建xml文档*/
newInstanceSAXBuilder();
/*2.基于xml文件路径创建xml文件对象*/
String classPath = Tools.getClassPath(); //通过工具类获取类路径
File xmlFile = new File(classPath+"com/study/doc/"+xmlFileName);//创建文件对象:类路径+包路径+文件名(注意包间用‘/’连接)
try {
/*3.使用SAXBuilder加载xml文件对象*/
document = saxbuilder.build(xmlFile);//build方法将加载file对象为document对象
/*4.解析xml文档*/
if(document!=null) {
/*获得根节点*/
Element root = document.getRootElement();
/*获得所有子元素*/
List<Element> studentList = root.getChildren();
/*循环遍历获取子元素存储的数据*/
for(Element e:studentList) {
Students stu = new Students();
/*getAttribute获取属性对象,getValue获得值,getChild获取子标签对象,getText获取标签的文本内容*/
stu.setID(e.getAttribute("ID").getValue());
stu.setName(e.getChild("name").getText());
stu.setSex(e.getChild("sex").getText());
String birth = e.getChild("birth").getText();
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(birth);//格式化日期获取Date对象
stu.setBirth(date);
stuList.add(stu);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stuList;
}
主要方法
new SAXBuilder().build(file);参数为file对象,为目标xml文件的file对象建立document对象并返回
new Document().getRootElement();返回xml文档的根元素,Element对象
new Element().getAttribute(name);通过属性的名称,返回元素的指定属性对象
new Element().getAttribute(name).getValue();通过属性名称,返回元素的指定属性的值
new Element().getChild(name);通过标签的名称,返回元素的指定子元素
new Element().getChild(name).getText();通过标签的名称,发挥元素的指定子元素的文本
JDOM写入文档
流程
- 创建XMLOutputter对象用来修改写入XML文档
- 基于XML路径创建XML文件对象
- 使用SAXBuilder加载XML文件对象
- 利用JDOM相关方法将修改信息写入到目标XML文件
代码实现
实习xml文件修改功能的方法
/**
* 对XML文档信息的修改
* @param xmlFile 需要修改的xml文档名
*/
public static void ModifyXML(String xmlFileName) {
/*创建字符输出流对象,用于写入目标文件*/
Writer out = null;
/*获得修改信息*/
Students stu = new Students();
stu = input();
/*创建SAXBuilder对象*/
newInstanceSAXBuilder();
/*1.创建XMLOutputter用来修改写入XML文档*/
newInstanceXMLOutputter();
/*2.基于XML路径创建XML文件对象*/
String classPath = Tools.getClassPath();//获取类路径
File xmlFile = new File(classPath+"com/study/doc/"+xmlFileName);
try {
/*3.使用SAXBuilder加载XML文件对象*/
document = saxbuilder.build(xmlFile);
/*4.将修改信息写入目标文件*/
/*获得根节点*/
Element root = document.getRootElement();
/*获得所有子元素*/
List<Element> children = new ArrayList<Element>();
children = root.getChildren();
/*将修改信息写入目标元素*/
for(Element e:children) {
if(stu.getID().equals(e.getAttribute("ID").getValue())) {//通过标识符ID锁定目标元素
Element name = e.getChild("name");
name.setText(stu.getName());
Element birth = e.getChild("birth");
birth.setText(new SimpleDateFormat("yyyy-MM-dd").format(stu.getBirth()));
Element sex = e.getChild("sex");
sex.setText(stu.getSex());
}
}
/*将修改完的元素写入目标文件中*/
out = new FileWriter(xmlFile);//写入目标文件的输出流
xmlOutput.output(document, out);//将document对象放入对应输出流来写入目标文件
} catch (Exception e) {
e.printStackTrace();
} finally {
/*关闭输出流*/
if(out!=null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
}
用于输入修改信息的方法
/**
* 此方法用来从控制台接收需要修改的数据
* 以ID作为唯一标识符,来区分不同的元素
* @return 返回修改后的数据封装的学生对象
*/
private static Students input() {
Students stu = new Students();
Scanner in = new Scanner(System.in);
System.out.println("请输入需要修改的学生ID:");
stu.setID(in.next());
System.out.println("请输入学生姓名:");
stu.setName(in.next());
System.out.println("请输入学生生日:");
String birth = in.next();
Date sdf = null;
try {
sdf = new SimpleDateFormat("yyyy-MM-dd").parse(birth);
} catch (ParseException e) {
e.printStackTrace();
}
stu.setBirth(sdf);
System.out.println("请输入学生性别:");
stu.setSex(in.next());
return stu;
}
主要方法
new XMLOutputter().output(doctype,outStream);此方法将文档对象写入目标文件,参数doctype为文件对象,outStream为将写入的目标文件的输出流
DOM4J解析XML文件
DOM4J概述
- DOM4J是由第三方提供扩展子JDOMAPI的一组解析XML文件的java实现,它只和Java相关
- DOM4J对XML文档实现与JDOM类似,JDOM将XML文档中的每个节点(node)称之为Element(元素),并提供对元素上下级元素的获取等实用方法
- DOM4J解析XML大体分为两步操作:
- 获取目标XML文档并解析,封装成运行时的Java对象进行处理
- 将运行时Java对象以XML文件方式写入硬盘存储
DOM4J写入XML文档
流程
- 创建DocumentFactory用来创建Document对象
- 使用DOM4J实现对Document对象操作
- 创建XMLWriter用来将Document对象写入XML文件
- 关闭相关文件流
代码实现(创建XML文档)
员工实体类
/***
* 员工实体类
*/
public class Employee {
private String code;
private String name;
private String sex;
private Date birth;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
XML文档解析类
/***
1. XML文档解析功能类DOM4J
2. */
public class DOM4JXMLManager {
/*创建用于创建Document对象的DocumentFactory*/
private final DocumentFactory docFactory = DocumentFactory.getInstance();
/*声明文件输出流*/
Writer writer = null;
/*声明用于写入XML文档的XMLWriter*/
XMLWriter xmlWriter = null;
/*声明进行XML文档操作的Document对象*/
Document document = null;
/**
* 录入员工信息的方法
* @return 员工对象封装的集合
*/
public List<Employee> input(){
Scanner in = new Scanner(System.in);
List<Employee> empList = new ArrayList<Employee>();
while(true) {
Employee emp = new Employee();
System.out.println("请输入员工编号:");
emp.setCode(in.next());
System.out.println("请输入员工姓名:");
emp.setName(in.next());
System.out.println("请输入员工性别:");
emp.setSex(in.next());
System.out.println("请输入员工出生年份:");
int year = in.nextInt();
System.out.println("请输入员工出生月份:");
int month = in.nextInt();
System.out.println("请输入员工出生日期:");
int date = in.nextInt();
emp.setBirth(Tools.toDate(year, month, date));
empList.add(emp);
System.out.println("继续录入请输入1,停止录入输入其他数字:");
if(in.nextInt()!=1)
break;
}
return empList;
}
/**
* 创建并写入XML文档的方法
* @param empList 需要写入的Employee数据的集合
* @param fileName 创建的XML文档名称
*/
public void createEmployeeXML(List<Employee> empList,String fileName) {
/*1.使用DocumentFactory创建Document对象*/
Document document = docFactory.createDocument("utf-8");//设置编码格式为utf8
/*2.利用DocumentFactory对象与Document对象创建XML文档根元素*/
Element rootEle = docFactory.createElement("employees");//创建元素rootEle
document.setRootElement(rootEle);//将rootELe设为根元素
/*3.根据数据长度循环创建子元素*/
if(!empList.isEmpty()&&empList!=null) {
for(Employee emp:empList) {
/*一级子元素*/
Element empEle = docFactory.createElement("employee");
/*二级子元素*/
Element codeEle = docFactory.createElement("code");
codeEle.setText(emp.getCode());
Element nameEle = docFactory.createElement("name");
nameEle.setText(emp.getName());
Element sexEle = docFactory.createElement("sex");
sexEle.setText(emp.getSex());
Element birthEle = docFactory.createElement("birth");
birthEle.setText(new SimpleDateFormat("yyyy/MM/dd").format(emp.getBirth()));
/*将二级子元素添加到父元素下*/
empEle.add(codeEle);
empEle.add(nameEle);
empEle.add(sexEle);
empEle.add(birthEle);
/*将一级子元素添加到根元素下*/
rootEle.add(empEle);
}
}
/*4.XML文档写入操作*/
String classPath = Tools.getClassPath();//获取类路径
File xmlFile = new File(classPath+"com/study/doc/"+fileName);//创建文件对象
try {
writer = new FileWriter(xmlFile);//实例化目标文件输出流
/*设置格式与编码*/
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
xmlWriter = new XMLWriter(writer,format);//利用目标文件的输出流实例化XMLWriter
xmlWriter.write(document);//将xml文档对象写入目标文件
} catch (IOException e) {
e.printStackTrace();
} finally {
/*5.关闭相关文件流*/
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
主要方法
new DocumentFactory.createElement(elementName);创建元素,参数为元素名
new Document.setRootElement(root);将参数root指向的元素设置为根元素
new Element().add(element);将参数element指向的元素设置为子元素
DOM4J读取xml文档
流程
- 基于xml文件路径创建File对象
- 创建SAXReader来加载xml文件为Document对象
- 利用DOM4J相关方法来解析xml文档
- 将数据封装为Java对象
代码实现
/**
* 读取XML文档的方法DOM4J
* @param fileName
* @return 读取到的数据封装的集合
*/
public List<Employee> toEmployeeFromXML(String fileName){
List<Employee> empList = new ArrayList<Employee>();
/*1.基于xml文档路径创建File对象*/
String classPath = Tools.getClassPath();
File xmlFile = new File(classPath+"com/study/doc/"+fileName);
/*2.创建SAXReader*/
SAXReader saxReader = new SAXReader();
Reader reader = null;
try {
reader = new FileReader(xmlFile);
/*3.创建Document*/
document = saxReader.read(xmlFile);
/*3.解析xml文档*/
if(document!=null) {
Element root = document.getRootElement();
List<Element> employeeEle = root.elements("employee");
/*4.封装数据为Java对像*/
for(Element e:employeeEle) {
Employee emp = new Employee();
emp.setCode(e.elementText("code"));
emp.setName(e.elementText("name"));
emp.setBirth(new SimpleDateFormat("yyyy/MM/dd").parse(e.elementText("birth")));
emp.setSex(e.elementText("sex"));
empList.add(emp);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
/*5.关闭文件流*/
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return empList;
}