XML解析-学习Pull和DOM4J的使用

很久没有写博客了,我认为黑马最最可贵的地方在于培养一个开发人员写博客的习惯。在写博客的过程当中,可以巩固以前的旧知识,同时增加了发现新问题的几率,对于提高自己是一个很好的途径。废话不多说,就将XML的两个常用解析器拿来记录一下。 一、Pull、DOM4J解析器概述 在概述部分,我都将这两个解析器按照自己的理解来阐述一下。自己是菜鸟,就不要写出高大上的话,这样才能真正把知识转化为自己的。 1.Pull解析器 Pull解析器是Android内置的XML解析器。Pull的内部,实现的是基于事件驱动的SAX解析思想,一次读取一行XML文件,并加载一行,解析一行。Pull的有点在于其可以控制SAX读取指针的动作,程序让它往下走,指针才会读取下一行。 2.DOM4J DOM4J是开发JDOM的意外产物。据说开发JDOM的一帮子人内讧,一帮说要这样,一帮说要那样,然后分家。分家出去的那帮人做了DOM4J,又据说性能等各方面完暴JDOM,成了现在最流行的XML解析器。书写简单,效率高,集合了SAX和DOM思想,怎一个“屌”字了得~ 二、两种解析器的应用 1.Pull解析器使用步骤 使用Pull解析XML文件的大致步骤如下: 第一步:创建一个解析器工厂 第二步:通过解析器工厂,获取一个解析器对象 第三步:为解析器设置一个输入流,关联需要解析的XML文件 假设这个需要解析的就是这个student.xml文件,并指定解析使用的字符编码是utf-8格式。 第四步:获取解析器事件类型,可以根据事件类型来执行相对应的操作 事件类型是一个整型数据,代表着解析器类当中的诸如START_DOCUMENT的一系列常量。 下面的例子,就是解析一个student.xml文件,并将文件中的每个元素,都封装成Student对象,存放入List集合中,这个例子的关键点在于分清楚每一个事件类型应该采取什么样的操作。 先来看看这个XML文件: number、name、age、sex、score这些元素,应该被封装成一个Student类,这个Student类如下: 写好了Student类,下面要做的就是解析XML文件。解析的整体思路就是利用Pull解析器的getEventType()方法,获取解析器当前的标签状态,判断该标签是起始标签还是结束标签,做出相应的动作。如果是起始标签,又可以使用解析器的getName()方法获取标签名,通过判断标签名,再进行进一步的操作。代码中有详细的注释。 示例代码: 程序输出结果: 解析并封装成功~ 除了解析,Pull也提供了写如一个XML文件的方法,通过XmlSerializer对象的一系列方法(序列化)实现。写入的方式相对简单,就是调用startDocument(),startTag(),text()等方法,创建标签即文本内容即可。下面的代码将创建一个名为stu.xml文件。 示例代码: 生成的stu.xml文档: 2.DOM4J解析器使用步骤 老大哥来了,使用起来真的是方便。DOM4J集合了SAX和DOM的思想,在关联解析文件的时候,用的是SAXReader对象,而对XML进行增删改查的过程,用的又是DOM的思想。不愧是解析思想的集大成者。废话不多说,用代码说明一下DOM4J的使用,真的是简单~ 2.1DOM4J解析XML文件的步骤 第一步:创建SAXReader对象 第二步:关联解析文件,得到该文件的Document对象,这是DOM思想的开始 2.2DOM4J回写(这里对于回写就不做说明啦)的步骤 DOM4J的回写是通过XMLWriter对象,配合OutputFormat对象实现的,简单看一下吧,用起来很方便。 第一步:创建OutputFormat对象,这个对象是用于格式化输出的XML文件,通过两个静态方法createPrettyPrint()和createCompactFormat()来创建格式化的输出和紧凑的输出;格式化的就是我们一般看到的XML格式,compact的格式就是将XML文件输出在一行,供计算机阅读;这里我们就是用pretty格式啦! 第二步:创建XMLWriter对象,这个对象接收OutputStream和OutputFormat对象作为参数 第三步:回写修改之后的XML对象,这个XML对象现在是以Document的形式存在于内存,调用write方法将他写回到XML文件 第四步:由于XMLWriter要开流,所以要关闭资源 完成啦~ 下面就用具体的代码来阐述如何用DOM4J来对XML文件进行增删改查的操作。先来看看Student.xml这个需要被操作的文件。 Student.xml 由于大部分方法都要获取Document对象,也都要回写Document对象,所以先将这两个方法封装到一个工具类中,方便调用。 DOM4JUtils工具类 写好了工具类,就可以开始对XML文件进行解析了,下面的代码中运用了JUnit Test的方式对每一个方法进行测试,就不需要写一个main方法,省去了在main方法中一个一个调用的麻烦。 JUnit小技巧:在方法上面,加上@Test注解(下面有示例),然后在报错行按下Ctrl+1导入JUnit包,接着就可以双击方法名——>Run as——>JUnit Test即可运行该方法;如果看到下图的绿色条,就是方法运行成功,没有报错 三、小案例 这个案例实现了一个简易的商品管理系统,用户可以选择需要的操作,完成对商品XML文件的增删改查操作。有兴趣就看看吧,不想写注释了。。。有点累咯大家见谅~大致的实现思想就是基于DOM4J的解析和回写。当然了,第一次启动程序的时候,需要先添加一些列的商品,然后在进行其他操作。代码里没有很严谨,没有对输入做校验,所以才叫简易系统嘛哈哈,我就不为难自己了~ pro.xml ProductManagingSystem KEEP CALM AND CARRY…

JavaEnhance——类加载器

一、概述 1.类加载器的定义 所有Java类在使用的时候都必须通过类加载器加载到内存。Java虚拟机可以安装多个类加载器,系统默认的,有三个主要的类加载器:BootStrap, ExtClassLoader, AppClassLoader。它们分别负责加载特定位置的类。 2.类加载器的性质 类加载器也是Java类。因此,类加载器也要被一个类加载器加载,才能工作。这么说来,必须有一个不是Java类的类加载,才能完成上述工作。这个类加载器就是BootStrap,它是所有类加载器的父类。 3.类加载器的继承关系 Java虚拟机中的所有类加载器都具有其父子关系的树形结构,在实例化每个加载器的对象时,需要为其指定一个父级类加载器对象或者默认采用系统类加载器为其父级类加载器。 二、委托机制 在类加载器的委托机制中,子类类加载器都会先委托其父类类加载器去寻找要加载的类;如果父类加载器寻找到该类,就直接加载该类;如果没有找到,就会逐级返回,直到回到子类加载器,由子类类加载器加载该类。 三、自定义类加载器 自定义类加载器必须继承ClassLoader类,并复写findClass()方法。 提示:没有复写loadClass()方法的原因在于,loadClass()方法会找其父类加载器,如果父类加载器无法完成类的加载,loadClass()方法回返回来调用findClass()方法。如果复写loadClass()方法,那么去调用父类的实现还需要自己动手写,代码复杂。所以只需要复写findClass()方法即可。 下面的例子实现了用自定义类加载器加载一个类,并将这个类进行加密解密,也就是说,只有自定义类加载器才能调用该类。 需要被加密的类: 自定义类加载器: 类加载器测试类: 程序输出结果:Shit happens…

JavaEnhance——枚举、注解及泛型

枚举 一、概述 如果一个变量的取值要被限定在一定的范围内,例如星期的取值,限定在1~7的范围内,并且想要在编译期就能指出变量取值超出范围的错误,就可以使用枚举。枚举相当于一个类,其中也可以定义构造方法,成员变量,普通方法和抽象方法。 二、枚举的应用 1.使用普通类模拟枚举 使用普通类模拟枚举的时候,首先将构造方法私有化,然后在类的内部创建常量,那么其他类在调用这个类的时候,只能得到模拟枚举类中的常量,不能new出新的值。 示例代码: 这样就实现了一个最基本的枚举类,除了类中定义的两个常量外,不可能再为weekDay赋另外的值。接下来,可以在模拟枚举类中加入方法。 示例代码: 这里只写了两个常量,如果有七个,那么这个nextDay()方法中的if else语句就会很长,为了避免长代码,可以将nextDay()定义为抽象方法,由每个子类对象去实现。 示例代码: 用抽象方法可以将大量的if else语句转换成由一个个独立的子类来实现该抽象方法,简化了代码。 2.定义枚举类在用普通类模拟了枚举类之后,现在定义一个真正的枚举类。在类中定义一个内部枚举类。 示例代码: 枚举类内部实现了toString()方法。下面为枚举类定义构造方法。 示例代码: 默认情况下,枚举的成员使用的都是无参构造方法。只要用到枚举类,里面的所有静态成员都会被初始化。如果指定要调用有参构造方法,只需在枚举成员后加上小括号,写入参数即可。 示例代码: 最最复杂的枚举,就是带有抽象方法的枚举,下面运用枚举实现一个交通灯系统。 示例代码: 三、枚举总结 1.枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后面要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面, 编译器会报错。 2.带构造方法的枚举 (1) 构造方法必须定义成私有(2) 如果有多个构造方法,在枚举元素后面加上小括号来调用指定的构造方法(3) 枚举元素MON和MON()的效果一样,都是调用默认的构造方法 3.带抽象方法的枚举 每个元素都是由枚举类的子类来生成的实例对象,这些子类可以采用类似内部类的方式来定义并实现枚举中的抽象方法。 4.枚举只有一个成员时,就可以作为一个单例的实现方式。 注解 一、概述 注解是JDK1.5开始的新特性,一个注解就是一个类,运用注解的时候就是创建了一个注解的实例对象。现行的框架,如Hibernate,Spring,EJB以及Struts2的一部分,都是基于注解技术。注解相当于一个标记,可以添加在包、类、字段、方法、方法的参数以及局部变量上。 二、常见注解 1.@SuppressWarnings该注解用于去除编译期出现的警告提示,如调用了过时方法时的警告提示 2.@Deprecated该注解用于标识一个方法等已经过时,不建议使用;添加了该注解的方法等,或被一根横线划过 3.@Override该注解用于标识一个方法是其父类中方法的复写;如果方法与父类中的方法不一致,会得到报错提示 三、元注解 元注解就是添加在注解类上的注解,用于标识该注解的生命周期以及可以添加的位置等。 1.@Retention @Retention注解有三个取值,分别对应着注解的生命周期,它们是:@RetentionPolicy.SOURCE,@RetentionPolicy.CLASS,@RetentionPolicy.RUNTIME;由于javac在编译源文件的时候或是classLoader将class文件加载到内存的过程中,会将一些注解去掉,会导致注解失效 2.@Target@Target元注解接收一个ElementType数组作为参数,指定某个注解类能被添加到哪些地方@Target({ElementType.METHOD, ElementType.TYPE})表示这个注解能被添加到方法和类上 四、注解的应用 1.创建自定义注解注解是一个类似接口的类,用@interface + 类名来表示。 示例代码: 将自定义注解类添加到一个类上 示例代码: 程序无打印结果,是因为自定义注解上没有添加标识该注解声明周期的元注解。 添加元注解:…