基于Dom4J实现XML快速解析(三)

news/2024/5/19 4:21:15 标签: Android, JAVA, XML生成, 反射, 设计模式

XMLParse之XML文件生成实现

前面实现了XML的设计和文件解析,对于XML文件的生成,原理依然是按照反射机制,将XML标签类实例逆向保存到dom4j.jar中的Element中,对照前面两篇文章,实现并不困难

思路分析

通过反射取到XML标签类中的各个变量的类型和值。
遇到List或者非属性对象需要创建新的标签元素。使用addElement()方法实现添加新的节点。
遇到StringIntegerFloatBoolean直接添加到当前元素的属性中即可

XmlGenerate.java中定义的write()方法为具体实现。
上代码:

private static void write(Element rootElement, Object object) throws InvocationTargetException, IllegalAccessException {

        Class<? extends Object> clazz = object.getClass();
        Field[] filds = clazz.getDeclaredFields();
        Method[] methods = clazz.getDeclaredMethods();
        for (Field fild : filds) {
            String type = fild.getGenericType().toString();
            String name;
            if (type.contains(".List")){//子节点 集合

                name = fild.getGenericType().toString();
                name = name.substring(name.lastIndexOf(".")+1,name.length()-1);
                for (Method method : methods) {
                    if (("get"+name.toLowerCase()+"s").equals(method.getName().toLowerCase())){
                        List list = (List) method.invoke(object);
                        if (list != null){
                            for (Object o : list) {
                                Element element = rootElement.addElement(name);
                                write(element,o);
                            }
                        }
                    }
                }
                System.out.println(fild.getName());
                System.out.println(fild.getType());
                System.out.println(fild.getDeclaringClass());
                System.out.println(fild.getGenericType());

            }else if (type.contains(".String")){//属性

                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        String s = (String) method.invoke(object);
                        if (s == null)
                            s = " ";
                        rootElement.addAttribute(fild.getName(),s);
                    }
                }


            }else if (type.contains(".Integer")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Integer s = (Integer) method.invoke(object);
                        rootElement.addAttribute(fild.getName(),s+"");
                    }
                }
            }else if (type.contains(".Float")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Float s = (Float) method.invoke(object);
                        rootElement.addAttribute(fild.getName(),s+"");
                        System.out.println("name"+fild.getName()+" value "+s);
                    }
                }
            }else if(type.contains(".Boolean")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Boolean s = (Boolean) method.invoke(object);
                        rootElement.addAttribute(fild.getName(),s+"");
                        System.out.println("name"+fild.getName()+" value "+s);
                    }
                }
            }else {//子节点 非集合

                name = fild.getGenericType().toString();
                name = name.substring(name.lastIndexOf(".")+1);
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Object obj = method.invoke(object);//获得子标签
                        if (obj!=null){
                            Element element = rootElement.addElement(name);
                            write(element,obj);
                        }
                    }
                }

            }
        }
    }

generate 生成XML文件

封装在XMLAPI.java文件中,writeObj2Xml()方法,只需要传入XML标签类实例和输出路径就可以生成XML文件。在writeObj2Xml()中调用了XmlGenerate.generate()

/**
     * Generate.
     *
     * @param object 数据源,待转化成xml的实体类
     * @param DesPath xml文件生成路径
     * @throws InvocationTargetException the invocation target exception
     * @throws IllegalAccessException    the illegal access exception
     * @throws IOException               the io exception
     */
    public static void generate(Object object,String DesPath)throws InvocationTargetException, IllegalAccessException, IOException {
        String name;
        Class<?> clazz = object.getClass();
        String rootname = clazz.getName();
        rootname = rootname.substring(rootname.lastIndexOf(".")+1);
        System.out.println(rootname);
        Field[] filds = clazz.getDeclaredFields();
        Method[] methods = clazz.getDeclaredMethods();
        Element root = DocumentHelper.createElement(rootname);
        // 创建文档并设置文档的根元素节点
        Document doucment = DocumentHelper.createDocument(root);

        for (Field fild : filds) {
            String type = fild.getGenericType().toString();
            if (type.contains(".String")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        String s = (String) method.invoke(object);
                        if (s == null)
                            s = "";
                        root.addAttribute(fild.getName(),s);
                        System.out.println("name"+fild.getName()+" value "+s);
                    }
                }
            }else  if (type.contains(".Integer")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Integer s = (Integer) method.invoke(object);
                        root.addAttribute(fild.getName(),s+"");
                    }
                }
            }else if (type.contains(".Float")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Float s = (Float) method.invoke(object);
                        root.addAttribute(fild.getName(),s+"");
                        System.out.println("name"+fild.getName()+" value "+s);
                    }
                }
            }else if(type.contains(".Boolean")){
                name = fild.getName();
                for (Method method : methods) {
                    String mName = method.getName();
                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Boolean s = (Boolean) method.invoke(object);
                        root.addAttribute(fild.getName(),s+"");
                        System.out.println("name"+fild.getName()+" value "+s);
                    }
                }
            }else if (type.contains(".List")){
                name = fild.getGenericType().toString();
                name = name.substring(name.lastIndexOf(".")+1,name.length()-1);
                for (Method method : methods) {
                    if (("get"+name.toLowerCase()+"s").equals(method.getName().toLowerCase())){
                        List list = (List) method.invoke(object);
                        for (Object o : list) {
                            Element element = root.addElement(name);

                            write(element,o);
                        }
                    }
                }
            }else {
                name = fild.getGenericType().toString();
                name = name.substring(name.lastIndexOf(".")+1);
                for (Method method : methods) {
                    String mName = method.getName();

                    if (("get"+name.toLowerCase()).equals(mName.toLowerCase())){
                        Object obj = method.invoke(object);//获得子标签
                        if (obj!=null){
                            Element element = root.addElement(name);

                            write(element,obj);
                        }
                    }
                }
            }
            // 设置XML文档格式
            OutputFormat outputFormat = OutputFormat.createPrettyPrint();
            // 设置XML编码方式,即是用指定的编码方式保存XML文档到字符串(String),这里也可以指定为GBK或是ISO8859-1
            outputFormat.setEncoding("UTF-8");
            //outputFormat.setSuppressDeclaration(true); //是否生产xml头
            outputFormat.setIndent(true); //设置是否缩进
            outputFormat.setIndent("    "); //以四个空格方式实现缩进
            outputFormat.setNewlines(true); //设置是否换行

            //添加
            FileOutputStream file = new FileOutputStream(DesPath);
            XMLWriter xmlwriter2 = new XMLWriter(file,outputFormat);
            xmlwriter2.write(doucment);
            xmlwriter2.flush();
            xmlwriter2.close();
        }
    }

写在最后,XML快速解析三篇文章是本人很早之前写的,刚刚用上CSDN,所以尝试着把文章发一下。文章内描述的内容与项目实际内容已经不太一致,但是整体结构,设计思想没有变化,感兴趣的童鞋可以到 GitHub:lijieqing/XMLParser 查看源码,大家共同进步,谢谢!


http://www.niftyadmin.cn/n/1568408.html

相关文章

Android NDK基本配置

Windows下Android ndk 配置 ndk包 本次安装用的是android ndk 版本为 android-ndk-r12b-windows-x86_64 环境变量配置 将解压后的ndk路径添加到PATH中&#xff0c;本机为“D:/ndk” Android项目配置 1.新建Android项目,local.properties加入ndk.dirD:\ndk 2.完成后&…

Activity的四种加载模式

在多Activity开发中&#xff0c;有可能是自己应用之间的Activity跳转&#xff0c;或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例&#xff0c;而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式&#xff0c;而不是使用默认的加载模…

PathMeasure 重点方法详解(文章有错,待校正)

PathMeasure 重点方法详解 前 最近准备系统学习一下Android知识&#xff0c;Path操作时遇到一个比较难理解的类PathMeasure,一番研究&#xff08;百度一下&#xff09;&#xff0c;记录一下自己的理解。在此特别感谢GcsSloop同学的博文&#xff0c;对于 Android 自定义 view 知…

PendingIntent学习小结

近日为解决android闹钟标签问题&#xff0c;分析了android的DeskClock应用&#xff0c;发现在AlarmReceiver.java类中用PendingIntent封装的Intent&#xff0c;通过putExtra存入alarm值&#xff0c;当标签重新设定时在当前类中值相应发生了改变&#xff0c;然而当通过intent启动…

GreenDao笔记(一)

最近在搜寻好的数据库操作框架&#xff0c;发现GreenDao确实不错&#xff0c;结合项目使用过程&#xff0c;记录下配置细节&#xff0c;以供随时查看 GreenDao 数据库配置 greenDao不做太多介绍&#xff0c;一个很厉害的数据库框架&#xff0c;每秒钟读写高达30000次&#xff…

Android开发中进程等级相关

Android五个进程等级 1、前台进程&#xff08;Foreground process&#xff09;&#xff1a;   用户当前工作所需要的。一个进程如果满足下列任何条件被认为是前台进程&#xff1a; 正运行着一个正在与用户交互的活动&#xff08;Activity对象的onResume()方法已经被调用&…

GreenDao笔记(二)

GreenDao进阶笔记&#xff0c;通过 注解 JAVA 对象描述数据库表结构&#xff0c;以及实现一对多、多对多的联系&#xff0c;简单直接上代码&#xff0c;后面有详细说明 配置代码 Entity public class Soldier{ //人员表Id(autoincrement true)private Long sID;Propertypriva…

mapbox 数据驱动样式

mapbox 数据驱动样式 data-driven styling1. 画面或者带孔的面(FillLayer)1.1 普通面1.2 带孔面 2. 热力图(HeatmapLayer)3. 聚合(Cluster)4. 圆图层(CircleLayer)5. 图层过滤点线面(Filter)6. 弹窗(Info Window)7. 碰撞检测(Collision Detection) data-driven styling 1. 画面…