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的属性值必须加引号("或’)
  • 实体引用:

&lt:<
&gt:>
&amp:&
&apos:’
&quot:"

  • 注释符《!–注释–》(英文符号)
  • 在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概述

  1. JDOM是由第三方提供和维护的一组标准的Java实现,用来以Java语言形式解析XML文档;因此它知识和与Java平台语言,JDOM不遵循任何DOM实现标准,它只和Java相关
  2. JDOM对XML文档实现最为简单的读写操作,JDOM将XML文档中的每个节点(node)称之为Element(元素),并提供对元素上下级元素的获取等实用方法
  3. JDOM解析XML大体分为两种操作
  1. 读取目标XML文档并解析,封装成运行时的Java对象进行处理
  2. 将运行的Java对象以XML文件方式写入硬盘存储

JDOM读取XML文档

流程

  1. 创建SAXBuilder用来构建加载目标XML文档
  2. 基于XML路径创建XML文件对象
  3. 使用SAXBuilder加载XML文件对象
  4. 利用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写入文档

流程

  1. 创建XMLOutputter对象用来修改写入XML文档
  2. 基于XML路径创建XML文件对象
  3. 使用SAXBuilder加载XML文件对象
  4. 利用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概述

  1. DOM4J是由第三方提供扩展子JDOMAPI的一组解析XML文件的java实现,它只和Java相关
  2. DOM4J对XML文档实现与JDOM类似,JDOM将XML文档中的每个节点(node)称之为Element(元素),并提供对元素上下级元素的获取等实用方法
  3. DOM4J解析XML大体分为两步操作:
  1. 获取目标XML文档并解析,封装成运行时的Java对象进行处理
  2. 将运行时Java对象以XML文件方式写入硬盘存储

DOM4J写入XML文档

流程

  1. 创建DocumentFactory用来创建Document对象
  2. 使用DOM4J实现对Document对象操作
  3. 创建XMLWriter用来将Document对象写入XML文件
  4. 关闭相关文件流

代码实现(创建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文档

流程

  1. 基于xml文件路径创建File对象
  2. 创建SAXReader来加载xml文件为Document对象
  3. 利用DOM4J相关方法来解析xml文档
  4. 将数据封装为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;
	}