反射解析xml
需求
通过反射写一个可以解析所有xml文档工具类:可以对所有的xml解析增删改查
xml名字固定是类名.xml
xml根标签:dangAn
xml中类名标签 就表示一个对象:Student.xml中的每个Student标签对应一个java类中的Student对象
类的id属性 定义为标签的id属性
类的其他属性 定义为标签的子标签
老师代码
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XmlUtil {
public static void main(String[] args) {
// Object obj=new Student();
// System.out.println(obj.getClass().getName());
// System.out.println(obj.getClass());
//String id, String sname, char sex, float score, boolean sdy
// addOne(new Student("stu_11", "韩梅梅", '女', 17f, true));
// addOne(new Student("stu_12", "韩信", '男', 27f, true));
// addOne(new Student("stu_13", "韩非子", '男', 37f, false));
////
// addOne(new Teacher(10011, "张三", "男", 3100f, new Date(0)));
// addOne(new Teacher(10012, "李四", "女", 3200f, new Date(0)));
// addOne(new Teacher(10013, "王五", "男", 3300f, new Date(0)));
//
// updateOne(new Student("stu_11", "韩xx", '妖', 11f, true));
// updateOne(new Teacher(10011, "张x", "妖", 1111f, new Date(0)));
Student stu=new Student();
stu.setId("stu_11");
System.out.println(getOne(stu));
Teacher t1=new Teacher();
t1.setId(10011);
System.out.println(getOne(t1));
}
public static void updateOne(Object obj){
try {
//获取class
Class cla=obj.getClass();
//获取类名
String className=cla.getSimpleName();
//获取xml文件
File file=new File("src/"+className+".xml");
if(!file.exists()){
throw new RuntimeException(file.getAbsolutePath()+"不存在!");
}
//获取obj的id属性值
Field fieldId=cla.getDeclaredField("id");
fieldId.setAccessible(true);
Object idValue=fieldId.get(obj);
//获取document对象
Document doc=xml2Doc(file);
//获取所有的类标签
NodeList classList=doc.getElementsByTagName(className);
for (int i = 0; i < classList.getLength(); i++) {
Element eleCla=(Element)classList.item(i);
//获取id属性
if(eleCla.getAttribute("id").equals(idValue+"")){
//更改当前标签的子标签的文本内容
//获取所有的属性
Field[] fieldArr=cla.getDeclaredFields();
for (Field field : fieldArr) {
String fieldName=field.getName();
field.setAccessible(true);
if(!fieldName.equals("id")){
Object fieldValue=field.get(obj);
//获取当前类标签下的子标签
Element eleZi=(Element)eleCla.getElementsByTagName(fieldName).item(0);
eleZi.setTextContent(object2Str(fieldValue));
}
}
break;
}
}
doc2Xml(file, doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Object getOne(Object obj){//参数对象只有id属性值
Object result=null;
try {
//获取class
Class cla=obj.getClass();
//获取类名
String className=cla.getSimpleName();
//获取xml文件
File file=new File("src/"+className+".xml");
if(!file.exists()){
throw new RuntimeException(file.getAbsolutePath()+"不存在!");
}
//获取obj的id属性值
Field fieldId=cla.getDeclaredField("id");
fieldId.setAccessible(true);
Object idValue=fieldId.get(obj);
//获取document对象
Document doc=xml2Doc(file);
//获取所有的类标签
NodeList classList=doc.getElementsByTagName(className);
for (int i = 0; i < classList.getLength(); i++) {
Element eleCla=(Element)classList.item(i);
//获取id属性
if(eleCla.getAttribute("id").equals(idValue+"")){
// //创建对象
// result=cla.newInstance();
// //给对象的id属性赋值
// fieldId.set(result, idValue);
result=obj;
//更改当前标签的子标签的文本内容
//获取所有的属性
Field[] fieldArr=cla.getDeclaredFields();
for (Field field : fieldArr) {
String fieldName=field.getName();
field.setAccessible(true);
if(!fieldName.equals("id")){
//获取当前类标签下的子标签
Element eleZi=(Element)eleCla.getElementsByTagName(fieldName).item(0);
String eleText=eleZi.getTextContent();//获取文本内容
//把字符串转化为field对应的类型
Object objValue=str2Object(field, eleText);
field.set(result, objValue);
}
}
break;
}
}
return result;
//doc2Xml(file, doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Object str2Object(Field field,String str){
Class type=field.getType();
if(type==int.class||type==Integer.class){
return Integer.parseInt(str);
}
if(type==short.class||type==Short.class){
return Short.parseShort(str);
}
if(type==byte.class||type==Byte.class){
return Byte.parseByte(str);
}
if(type==long.class||type==Long.class){
return Long.parseLong(str);
}
if(type==float.class||type==Float.class){
return Float.parseFloat(str);
}
if(type==double.class||type==Double.class){
return Double.parseDouble(str);
}
if(type==boolean.class||type==Boolean.class){
return Boolean.parseBoolean(str);
}
if(type==char.class||type==Character.class){
return str.charAt(0);
}
if(type==Date.class){
try {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
return str;
}
public static void deleteOne(Object obj){//参数对象只有id属性值
try {
//获取class
Class cla=obj.getClass();
//获取类名
String className=cla.getSimpleName();
//获取xml文件
File file=new File("src/"+className+".xml");
if(!file.exists()){
throw new RuntimeException(file.getAbsolutePath()+"不存在!");
}
//获取obj的id属性值
Field fieldId=cla.getDeclaredField("id");
fieldId.setAccessible(true);
Object idValue=fieldId.get(obj);
//获取document对象
Document doc=xml2Doc(file);
//获取所有的类标签
NodeList classList=doc.getElementsByTagName(className);
for (int i = 0; i < classList.getLength(); i++) {
Element eleCla=(Element)classList.item(i);
//获取id属性
if(eleCla.getAttribute("id").equals(idValue+"")){
eleCla.getParentNode().removeChild(eleCla);
break;
}
}
doc2Xml(file, doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void addOne(Object obj){
try {
//获取class
Class cla=obj.getClass();
//获取类名
String className=cla.getSimpleName();
//获取xml文件
File file=new File("src/"+className+".xml");
if(!file.exists()){
createFile(file);
}
//获取document对象
Document doc=xml2Doc(file);
//获取根标签
Element root=(Element)doc.getElementsByTagName("dangAn").item(0);
//创建标签
Element eleClass=doc.createElement(className);
//获取所有属性
Field[] arr=cla.getDeclaredFields();
for (Field field : arr) {
field.setAccessible(true);
String fieldName=field.getName();
Object fieldValue=field.get(obj);//获取属性的值
if(fieldName.equals("id")){
eleClass.setAttribute("id", fieldValue+"");
}else{
//子标签
Element eleZi=doc.createElement(fieldName);
eleZi.setTextContent(object2Str(fieldValue));
eleClass.appendChild(eleZi);
}
}
root.appendChild(eleClass);
doc2Xml(file, doc);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void createFile(File file){
BufferedWriter bout=null;
try {
bout=new BufferedWriter(new FileWriter(file));
bout.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
bout.newLine();
bout.write("<dangAn>");
bout.newLine();
bout.write("</dangAn>");
bout.flush();
} catch (Exception e) {
throw new RuntimeException(e);
}finally{
if(bout!=null){
try {
bout.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
// 由xml获取document对象
public static Document xml2Doc(File file) {
try {
// 获取文档解析器工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 获取文档解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();// 实例工厂模式:
// 通过解析器对象的parse 由xml获document对象
return builder.parse(file);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 吧document对象刷新到xml中
public static void doc2Xml(File file, Document doc) {
try {
// 创建Transformer工厂对象
TransformerFactory factory = TransformerFactory.newInstance();
// 创建Transformer对象
Transformer tf = factory.newTransformer();
// 设置编码集合:默认utf-8
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// 调用taranform方法把doc的信息刷新到xml中
tf.transform(new DOMSource(doc), new StreamResult(file));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//把参数filed的值转化为字符串
private static String object2Str(Object fieldValue){
if(fieldValue.getClass()==Date.class){
Date date=(Date)fieldValue;
return date.toLocaleString();
}
return fieldValue+"";
}
}
// xml名字固定是类名.xml
// xml根标签:dangAn
// xml中类名标签 就表示一个对象:Student.xml中的每个Student标签对应一个java类中的Student对象
// 类的id属性 定义为标签的id属性
// 类的其他属性 定义为标签的子标签
自己代码
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author shkstart
* @create 2021-10-29 17:28
* 通过反射写一个可以解析所有xml文档工具类:可以对所有的xml解析增删改查
* xml名字固定是类名.xml
* xml根标签:dangAn
* xml中类名标签 就表示一个对象:Student.xml中的每个Student标签对应一个java类中的Student对象
* 类的id属性 定义为标签的id属性
* 类的其他属性 定义为标签的子标签
*/
public class XmlCRUD<T> {
private Document document;
private Class<T> clazz;
private File file;
public XmlCRUD(Class<T> clazz, String path) {
if (path.matches("^.+\\.xml$")) { //判断是否是 .xml结尾的
this.file = new File(path);
if (file.exists()) {
this.document = xmlParse(file);
this.clazz = clazz;
return; //结束
}
throw new RuntimeException("路径不存在");
}
throw new RuntimeException("不是 .xml为后缀的文件");
}
public T getOneById(String id) {
if (id != null && !"".equals(id)) {
NodeList classLabel = document.getElementsByTagName(clazz.getSimpleName());//获取该对象标签
for (int i = 0; i < classLabel.getLength(); i++) {
Node node = classLabel.item(i);
if (node instanceof Element) {
Element child = (Element) node;
if (child.hasAttributes()) {
String xid = child.getAttribute("id");
if (id.equals(xid)) {
if (child.hasChildNodes()) {
try {
T t = clazz.newInstance();
NodeList childList = child.getChildNodes();
for (int k = 0; k < childList.getLength(); k++) {
Node item = childList.item(k);
if (item instanceof Element) {
Element childNode = (Element) item;
Field f2 = clazz.getDeclaredField(childNode.getNodeName());//根据标签名字创建 field对象进行注入
f2.setAccessible(true);
f2.set(t, parseType(f2.getType(), childNode.getTextContent()));//设置成员变量
}
}
return t;
} catch (InstantiationException | IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
}
}
}
}
}
return null;
}
public List<T> getAllList() {
NodeList classLabel = document.getElementsByTagName(clazz.getSimpleName());//获取该对象标签
if (classLabel.getLength() != 0) {
ArrayList<T> list = new ArrayList<>();//用于存储对象
for (int i = 0; i < classLabel.getLength(); i++) {
Element eleSon = (Element) classLabel.item(i); //获取单个子标签
try {
/*
* 两种方式:
* 如果有属性,封装属性
* ==》在封装标签
* 没有属性:封装标签
*
* */
//1. 有属性
if (eleSon.hasAttributes()) {//判断是否有 属性
T t = clazz.newInstance(); //创建对象
NamedNodeMap attrList = eleSon.getAttributes(); //获取 attr集合
for (int j = 0; j < attrList.getLength(); j++) {
Node node = attrList.item(j);//获取属性
if (node instanceof Attr) {//是否 是属性
Attr attr = (Attr) node;
System.out.println(attr.getValue() + " : " + attr.getName());
Field f1 = clazz.getDeclaredField(attr.getName());//根据 name获取指定的field字段进行设置
f1.setAccessible(true);
f1.set(t, parseType(f1.getType(), attr.getValue()));
}
}
if (eleSon.hasChildNodes()) {
NodeList childList = eleSon.getChildNodes();//获取子标签
for (int k = 0; k < childList.getLength(); k++) {
Node node = childList.item(k);
if (node instanceof Element) { //如果是 element元素
Element child = (Element) node;
Field f2 = clazz.getDeclaredField(child.getNodeName());//根据标签名字创建 field对象进行注入
f2.setAccessible(true);
f2.set(t, parseType(f2.getType(), child.getTextContent()));//设置成员变量
}
}
}
list.add(t);//添加到集合
} else {//没有属性
if (eleSon.hasChildNodes()) {
T t2 = clazz.newInstance();//创建对象
NodeList childList = eleSon.getChildNodes();//获取子标签
for (int k = 0; k < childList.getLength(); k++) {
Node node = childList.item(k);
if (node instanceof Element) { //如果是 element元素
Element child = (Element) node;
Field f2 = clazz.getDeclaredField(child.getNodeName());//根据标签名字创建 field对象进行注入
f2.setAccessible(true);
f2.set(t2, parseType(f2.getType(), child.getTextContent()));//设置成员变量
}
}
list.add(t2);//添加到集合
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
return null;
}
//类型判断 基本类型
public Object parseType(Class<?> tClass, String parameter) {
if (tClass == String.class) {
return parameter;
} else if (tClass == Byte.class) {
return Byte.valueOf(parameter);
} else if (tClass == Short.class) {
return Short.valueOf(parameter);
} else if (tClass == Integer.class) {
return Integer.valueOf(parameter);
} else if (tClass == Long.class) {
return Long.valueOf(parameter);
} else if (tClass == Float.class) {
return Float.valueOf(parameter);
} else if (tClass == Double.class) {
return Double.valueOf(parameter);
} else if (tClass == Character.class) {
return parameter.charAt(0);
} else if (tClass == Date.class) {
return new Date(parameter);
} else {
return parameter;
}
}
public void DeleteById(int id) {
NodeList classLabel = document.getElementsByTagName(clazz.getSimpleName());
if (classLabel.getLength() != 0) {
for (int i = 0; i < classLabel.getLength(); i++) {
Element eleSon = (Element) classLabel.item(i);
int noid = Integer.parseInt(eleSon.getAttribute("id"));
if (noid == id) {
eleSon.getParentNode().removeChild(eleSon);
break;
}
}
}
//把doc刷新到xml中
xmlFlush(this.document, this.file);
}
public void addOne(Object... objects) {
//获取dangAn标签
Element root = (Element) document.getElementsByTagName("dangAn").item(0);
//创建 该类的标签
Element classLabel = document.createElement(clazz.getSimpleName());
// 添加属性
Field[] fields = clazz.getDeclaredFields();
if (fields.length == objects.length) { //有id 添加 attribute
//添加 id
classLabel.setAttribute(fields[0].getName() + "", objects[0] + "");
//添加标签
for (int i = 1; i < fields.length; i++) {
Element eleSon = document.createElement(fields[i].getName() + "");
//根据类型解析 【多此一举】
eleSon.setTextContent(parseType(objects[i].getClass(), objects[i] + "").toString());
classLabel.appendChild(eleSon);
}
root.appendChild(classLabel);
} else if ((fields.length - 1) == objects.length) {//不添加 attribute
for (int i = 1; i < fields.length; i++) {
Element eleSon = document.createElement(fields[i].getName() + "");
eleSon.setTextContent(objects[i] + "");
classLabel.appendChild(eleSon);
}
root.appendChild(classLabel);
} else {
throw new RuntimeException("长度超出");
}
//把doc刷新到xml中
xmlFlush(this.document, this.file);
}
// 由xml获取document对象
private Document xmlParse(File file) {
try {
// 获取文档解析器工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 获取文档解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();// 实例工厂模式:
// 通过解析器对象的parse 由xml获document对象
return builder.parse(file);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 把document对象刷新到xml中
private static void xmlFlush(Document doc, File file) {
try {
// 创建Transformer工厂对象
TransformerFactory factory = TransformerFactory.newInstance();
// 创建Transformer对象
Transformer tf = factory.newTransformer();
// 设置编码集合:默认utf-8
tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
// 调用taranform方法把doc的信息刷新到xml中
tf.transform(new DOMSource(doc), new StreamResult(file));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}