反射解析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);
        }
    }

}
posted @ 2021-11-01 10:57  MikiKawai  阅读(87)  评论(0编辑  收藏  举报