javaSE——XML+泛型+反射案例

XML

1 简介

(1)XML指可扩展标记语言(eXtensible Markup Language)
(2)用途:按照树形结构存储数据
(3)标记使用语法:

空标记
	<标记名   属性列表/>
非空标记
	<标记名   属性列表>   标记内容   </标记名>
	
说明:
	属性语法:属性名="属性值"
	标记内容=文本+子标记

(4)文本中的特殊字符处理:
a. 实体引用
b. 字符引用
c. CDATA段: <![CDATA[ .... ]]>

(5)规范的XML文档:
a. 必须要有声明,且在第一行
b. 有且仅有一个根节点
c. 区别大小写
d. 命名不能以数字开头

XML不会做任何事情,被设计用来结构化、存储数据以及传输信息,是独立于软件和硬件的信息传输工具。XML标签没有被预定义,需要自行定义标签(可以发明自己的标签),是对HTML的补充,不会替代HTML。

下面实例是 Jani 写给 Tove 的便签,存储为 XML:

<?xml version="1.0" encoding="UTF-8"?>   // 声明
<note>  // 根元素(像在说:"本文档是一个便签")
<to>Tove</to>  // 4 个子元素
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。上面的这条便签具有自我描述性。它包含了发送者和接受者的信息,同时拥有标题以及消息主体。但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。

(简介来自:https://www.runoob.com/xml/xml-intro.html)

2 DOM4J解析XML文档

DOM(Document Object Model 文档对象模型)定义了访问和操作文档的标准方法;
(1)简介
DOM4J是用java语言编写的专门用于XML文档操作的组件(外部类库)。

(2)下载
DOM4J的组件jar包

(3)使用

A. 把DOM4J的jar包导入到项目中
在项目根目录下,创建一个lib文件夹,将jar拷贝到lib中;
选中项目根目录,鼠标右键-properties,找到JavaBuildPath,在Libraries中使用AddJars将lib文件夹中的jar导入到项目中使用。

B. 在项目中使用DOM4J的API

a. 获得Document对象
	a1.  读取XML文件,获得document对象                               
	SAXReader reader = new SAXReader();
	Document   document = reader.read(new File("csdn.xml"));	
	
	a2.  解析XML形式的文本,得到document对象.                  
	String text = "<csdn></csdn>";
	Document document = DocumentHelper.parseText(text);	
	
	a3.  主动创建document对象.                  
	Document document = DocumentHelper.createDocument();
	//创建根节点
	Element root = document.addElement("csdn");

b. 将Document对象的信息写入XML文档
	b1.  不设置编码,直接写入的形式.
	XMLWriter writer = new XMLWriter(new  FileWriter("ot.xml"));
	writer.write(document);
	writer.close();    
	
	b2.  设置编码格式写入的形式.
	OutputFormat format = OutputFormat.createPrettyPrint();
	// 创建文件输出的时候,自动缩进的格式                         
	format.setEncoding("UTF-8");//设置编码  
	XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);       							writer.write(document);      
	writer.close();

c. 对Document对象进行操作		
	c1. 节点操作
		//获取根节点
		Element  root=document.getRootElement();

		//获取子节点
		List<Element>   list1=父节点对象.elements();//所有子节点
		List<Element>   list2=父节点对象.elements("子节点名称");//所有名称为XXX的子节点
		
		Element   e=父节点对象.element("子节点名称");//第一个叫XXX的子节点

		//获取和设置节点的文本
		节点对象.getText();
		节点对象.setText("文本");
		
		//添加CDATA段
		节点对象.addCDATA(“cdata区域”);


		//通过父节点,添加新节点
		父节点对象.addElement("新节点名");

		//通过父节点,删除某个节点
		父节点对象.remove(子节点对象);
		
	c2. 属性操作
		//获取属性
		Attribute   a=节点对象.attribute("属性名");
		List<Attribute>   as=节点对象.attributes();
		
		//获取属性的名字和值
		String name=a.getName();

		String value=a.getValue();
		String  text=a.getText();
		
		//添加新属性
		节点对象.addAttribute("属性名","属性值");

		//设置已有属性的值
		节点对象.addAttribute("属性名","属性值");
		a.setText("文本");	

		//删除已有的属性
		节点对象.remove(a);

其他dom4j操作相关参考:
https://www.cnblogs.com/forlina/archive/2011/06/09/2076534.html

3 XML+泛型+反射 案例

需求:学生管理系统,可以对学生信息进行增、删、修改、删除操作
目的:操作xml元素的增删改查

当使用DOM4J,还有经常用到的几种方法:

SAXReader.read(xmlSource)() - 构建XML源的DOM4J文档。
Document.getRootElement() - 得到的XML的根元素。
Element.node(index) - 获得在元素特定索引XML节点。
Element.attributes() - 获取一个元素的所有属性。
Node.valueOf(@Name) - 得到元件的给定名称的属性的值。

拓展:利用XPath应用解析xml文件。(和DOM4J是一个整体,实际上是它的一个工具,要导包)单纯使用dom访问节点时,需要一层一层的处理,如果有了XPath,定位节点变得轻松,可以根据路径表达式快速检索元素、属性。

1. Student类封装学生信息(Student.java)
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
 * 实体类封装学生信息
 */
public class Student implements Serializable{
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private String birthday;
	private String gender;
	private String major;
	private String calssName;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
//		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");
//		String time = sdf.format(birthday);
		this.birthday = birthday;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String getMajor() {
		return major;
	}
	public void setMajor(String major) {
		this.major = major;
	}
	public String getCalssName() {
		return calssName;
	}
	public void setCalssName(String calssName) {
		this.calssName = calssName;
	}
	public Student() {
		// 学号自动生成,生成规则为当年年份+5位数迭代数据例如,201900001,201900002,201900003...
		int year = Calendar.getInstance().get(Calendar.YEAR)*100000+(++StudentService.startTime);
		this.id = year;
	}
	public Student(String name, String birthday, String gender, String major, String calssName) {
		this();
		this.name = name;
		this.birthday = birthday;
		this.gender = gender;
		this.major = major;
		this.calssName = calssName;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", birthday=" + birthday + ", gender=" + gender
				+ ", major=" + major + ", calssName=" + calssName + "]";
	}
	
}

2. xml存储数据(student.xml)
<?xml version="1.0" encoding="UTF-8"?>
<students>
	<student name="杨越帅" birthday="21" gender="男" major="计算机" calssName="201班"></student>
	<student name="孔皓" birthday="24" gender="男" major="计算机" calssName="201班"></student>
	<student name="李静"  birthday="30" gender="女" major="计算机" calssName="201班"></student>
	<student name="刘勤辉" birthday="24" gender="男" major="计算机" calssName="201班"></student>
	<student name="杨生"  birthday="26" gender="男" major="计算机" calssName="201班"></student>
	<student name="杨生2"  birthday="26" gender="男" major="计算机" calssName="201班"></student>	
</students>

3. 封装操作XML文件功能方法(ReadWriteXML.java)

注意:导入dom4j的jar包
点击链接下载:dom4j-1.6.1.jar

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class ReadWriteXML {
	/**
	 * 直接给路径获得Document
	 */
	public Document getDocument(String path) {
		SAXReader saxReader = new SAXReader();
		Document document = null;
		try {
			document = saxReader.read(path);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return document;
	}
	/**
	 * 给路径获得根元素
	 */
	public Element getRootElement(String path) {
		if(!new File(path).exists()) {
			return creatXML(null,path).getRootElement();
		} else {
			return getDocument(path).getRootElement();
		}
	}
	/**
	 * 产生一个新的XML文件
	 */
	@SuppressWarnings({ "unused", "null" })
	public Document creatXML(Document document, String path) {
		if(document == null) {
			document = DocumentHelper.createDocument();
			// 创建根元素
			Element root = DocumentHelper.createElement("students");
			document.add(root);
		}
		// 创建流
		OutputStream outputStream = null;
		XMLWriter xmlWriter = null;
		// 持久化
		try {
			outputStream = new FileOutputStream(path);
			xmlWriter = new XMLWriter(outputStream);
			xmlWriter.write(document);
			xmlWriter.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(xmlWriter == null) {
					xmlWriter.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(xmlWriter == null) {
					outputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return document;
	}
}
4. 封装操作XML的工具类(ServiceUtil.java)
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Element;
public class ServiceUtil {
	ReadWriteXML readWriteXML = new ReadWriteXML();
	/**
	 * 反射和泛型
	 */
	@SuppressWarnings("deprecation")
	public<T> List<T> selectAll(Class<T> class1, String path) {
		// 获得根目录
		Element root = readWriteXML.getRootElement(path);
		List<T> list = new ArrayList<>();
		// 获得二级目录
		List<Element> twos = root.elements();
		// <student name="杨越帅" birthday="21" gender="男" major="计算机" calssName="201班"></student>
		for(Element element : twos) {
			// 获得所有标签的属性
			List<Attribute> listAttr = element.attributes();
			// 创建对象
			T t;
			try {
				t = class1.newInstance();
				for(Attribute attribute : listAttr) {
					// 进行比较,对应的属性一致,给对象属性赋值
					// 标签属性的名字
					String attrName = attribute.getName().trim();
					// 字段属性
					Field fieldName;
					try {
						// 查找对应属性
						fieldName = class1.getDeclaredField(attrName);
						// 异常
						if(fieldName != null) {
							// 获得标签属性值
							String valueSrc = attribute.getValue();
							Object value = null;
//							System.out.println(fieldName.getType());
//							System.out.println(Integer.class);
							// 判断属性的类型
							if(fieldName.getType() == Integer.class) {
								value = Integer.parseInt(valueSrc);
							} else if (fieldName.getType() == Character.class) {
								value = new Character(valueSrc.charAt(0));
							} else {
								value = valueSrc;
							}
							// 有此属性给属性赋值(调用set方法给属性赋值)
							fieldName.setAccessible(true);
							fieldName.set(t, value);
							
						}
					} catch (NoSuchFieldException e) {
						e.printStackTrace();
					} catch (SecurityException e) {
						e.printStackTrace();
					}
				}
				list.add(t);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
}
5. 操作学生类的类(StudentService.java)

对学生进行增 删 改 查操作:

import java.util.Iterator;
import java.util.List;
public class StudentService {
	public static int startTime = 0;// 在实体类计算学号时用到
	String path = "src/day10work/student.xml";
	ServiceUtil serviceUtil = new ServiceUtil();
	/**
	 * 查询所有学生信息
	 */
	public List<Student> selectAll() {
		List<Student> list =  serviceUtil.selectAll(Student.class, path);
		return list;
	}
	/**
	 * 根据学生ID查询信息
	 */
	public void selectById(List<Student> list, Integer id) {
		boolean isSelect = false;
		for(Student student : list) {
			if(student.getId().equals(id)) {
				isSelect = true;
				System.out.println(student);
			}
		}
		if(!isSelect) {
			System.out.println("查无此人~");
		}
	}
	/**
	 * 根据姓名模糊查询
	 */
	public void selectByName(List<Student> list, String name) {
		boolean isSelect = false;
		for(Student student : list) {
			if(student.getName().contains(name)) {
				isSelect = true;
				System.out.println(student);
			}
		}
		if(!isSelect) {
			System.out.println("查无此人~");
		}
	}
	/**
	 * 根据ID删除学生信息
	 */
	public void deleteById(List<Student> list, Integer id) {
		boolean isDelete = false;
		Iterator<Student> it = list.iterator();
		while(it.hasNext()) {
			if(it.next().getId().equals(id)) {
				isDelete = true;
				it.remove();
				System.out.println("删除成功!");
			}
		}
		if(!isDelete) {
			System.out.println("无此学号,删除失败");
		}
	}
	/**
	 * 利用ID,修改学生其他信息
	 */
	public void update(List<Student> list, int sid, String sname, String sbirthday) {
		boolean isUpdate = false;
		for(Student student : list) {
			System.out.println("aaa");
			System.out.println(student.getId());
			System.out.println(student.getId().equals(sid));
			if(student.getId().equals(sid)) {
				System.out.println("bb");
				student.setName(sname);
				student.setBirthday(sbirthday);
				isUpdate = true;
				System.out.println("修改成功!");
				System.out.println(student);
			}
		}
		if(!isUpdate) {
			System.out.println("修改失败~");
		}
	}
}
6. 测试类(TestAll.java)
import java.util.List;
import java.util.Scanner;
public class TestAll {
	static StudentService service = new StudentService();
	static List<Student> students = service.selectAll();
	private static void choose() {
		System.out.println("请输入:1.查询全部     2.按学号查询    3.按姓名模糊查询   4.删除    5.修改   6.退出");
		Scanner scanner = new Scanner(System.in);
		int i = scanner.nextInt();
		switch (i) {
		case 1:
			for(Student stu : students) {
				System.out.println(stu);
			}
			choose();
			break;
		case 2:
			System.out.println("请输入学号:");
			Integer id = scanner.nextInt();
			service.selectById(students, id);
			choose();
			break;
		case 3:
			System.out.println("请输入姓名:");
			String name = scanner.next();
			service.selectByName(students, name);
			choose();
			break;
		case 4:
			System.out.println("请输入要删除学生的学号:");
			Integer deleid = scanner.nextInt();
			service.deleteById(students, deleid);
			choose();
			break;
		case 5:
			System.out.println("请输入要修改学生的学号:");
			int sid = scanner.nextInt();
			System.out.println("请输入修改后的学生的信息:");
			System.out.println("姓名:");
			String sname = scanner.next();
			System.out.println("年龄:");
			String sbirthday = scanner.next();
			Student stude = new Student();
			service.update(students,sid,sname,sbirthday);
			choose();
			break;
		case 6:
			System.exit(0);
		default:
			break;
		}
	}
	public static void main(String[] args) {
		choose();
	}
}

7. 运行结果

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值