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

news/2024/5/19 5:44:17 标签: Android, JAVA, XML, 反射, 设计模式之组合

XMLParse之XML文件解析实现

第一篇已经介绍了基础的XMLAttributeXMLBaseXMLNoChildsXMLHasKids四个类的设计,接下来我们根据上面四个类进行XML文件的解析。
提示,在解析XML时用到了第三方的dom4j.jar导入即可(站在巨人肩膀上真的很好)。

我们将XML文件的格式用JAVA类表示出来
举例:

<Books type="文艺">
    <Book name="西游记"/>
    <Book name="红楼梦"/>
</Books>

我们用JAVA这样描述:

class Book{
    private String name;
    //构造方法和get set
}
class Books{
    private String type;
    private List<Book> books;
    //构造方法和get set
    //注意,在构造方法中要实现books的实例化
}

这两种类称为XML标签类
将这两个XML标签类放到指定位置就可以通过反射找到他们,然后在调用transform()进行转换

XML解析过程

XML解析过程:读取文件、生成XMLBase、调用transform()转化。

读取文件

通过dom4j.jar进行读取,本人用的是SAXReader来进行读取。

生成XMLBase

XMLReader.java中定义了XMLparse()方法,其中用到了递归处理,因为子标签也可能有子标签,递归结束标志就是当前标签是无子标签。

public static void XMLparse(Element rootElement,XMLBase root){
        XMLBase cur;
        //判断标签元素是否还有子元素
        if (rootElement.elements().size()>0){
            //含有子元素,创建XMLBase
            cur = new XMLHasKids(rootElement.getName());
            //给XMLBase中的属性集合赋值
            List<Attribute> attributes = rootElement.attributes();
            List<XMLAttribute> xmlAttributes = new ArrayList<>();
            for (Attribute attribute : attributes) {
                xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
            }
            cur.setXMLAttributes(xmlAttributes);
            //将新创建的XMLBase添加到上一级的子标签集合中
            root.addKids(cur);
            //对子元素的子元素进行递归赋值
            List<Element> childelement = rootElement.elements();
            for (Element element : childelement) {
                XMLparse(element,cur);
            }
        }else {
            //当没有子元素时,创建XMLBase对象
            cur = new XMLNoChilds(rootElement.getName());
            //给XMLBase对象中的属性集合赋值
            List<Attribute> attributes = rootElement.attributes();
            List<XMLAttribute> xmlAttributes = new ArrayList<>();
            for (Attribute attribute : attributes) {
                xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
            }
            cur.setXMLAttributes(xmlAttributes);
            //将新创建的XMLBase添加到上一级的子标签集合中
            root.addKids(cur);
        }
    }

transform转换

对于已经生成XMLBase的XML文件,只需要调用XMLBase的transform()方法就能获得对应的XML标签类实例。此方法已经封装到了XMLAPI.java中。

    /**
     * Read xml object.
     *
     * @param inputStream the input stream of xml file
     * @return the object
     */
    public static Object readXML(InputStream inputStream){
        Element rootElement = null;
        SAXReader reader = new SAXReader();
        try {
            document = reader.read(inputStream);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //先 将root 节点解析出来
        if (document != null)rootElement = document.getRootElement();
        XMLBase root = new XMLHasKids(rootElement.getName());
        List<Attribute> attributes = rootElement.attributes();
        List<XMLAttribute> xmlAttributes = new ArrayList<>();
        for (Attribute attribute : attributes) {
            xmlAttributes.add(new XMLAttribute(attribute.getName(),attribute.getValue()));
        }
        root.setXMLAttributes(xmlAttributes);

        //利用递归 将子节点逐一解析 放入xmlbase 中
        List<Element> childelement = rootElement.elements();
        for (Element element : childelement) {
            XmlReader.XMLparse(element,root);
        }

        return root.transform();
    }

返回的是Object对象,直接强转即可。到此XML解析设计结束。下一篇我们研究XML文件的生成。

最后说一下,上一篇中XMLBase抽象类中是定义了一个方法valueFormat()是在transform()时对属性进行赋值的,现在贴出来,当然还有很多需要优化的地方。

    /**
     *数值转换方法,根据不同的数值类型将值传入
     *关键是异常捕获后的赋值,避免赋值出现空值
     */
    protected void valueFormat(String type,Object o,XMLAttribute XMLAttribute,Method method) throws InvocationTargetException, IllegalAccessException {
        if (type.contains(".String")){
            method.invoke(o,XMLAttribute.getValues());
        }else if (type.contains(".Integer")){
            Integer values;
            try {
                values = Integer.valueOf(XMLAttribute.getValues());
            }catch (NumberFormatException e){
                e.printStackTrace();
                values = 0;
            }
            method.invoke(o,values);
        }else if (type.contains(".Float")){
            Float values;
            try {
                values = Float.valueOf(XMLAttribute.getValues());
            }catch (NumberFormatException e){
                values = 0.0f;
                e.printStackTrace();
            }
            method.invoke(o,values);
        }else if(type.contains(".Boolean")){
            Boolean values;
            values = Boolean.valueOf(XMLAttribute.getValues());
            method.invoke(o,values);
        }
    }

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

相关文章

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

XMLParse之XML文件生成实现 前面实现了XML的设计和文件解析&#xff0c;对于XML文件的生成&#xff0c;原理依然是按照反射机制&#xff0c;将XML标签类实例逆向保存到dom4j.jar中的Element中&#xff0c;对照前面两篇文章&#xff0c;实现并不困难 思路分析 通过反射取到XML标…

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…