本博客讲的XML解析,使用的是dom4j。

首先建立一个maven项目,在dom.xml中引入相应的dom4j的版本。作者下载的是热度很高的1.6.1版本。maven的使用在这里不做详细讲解。

引入成功后,来简单了解该包提供的API

1.org.dom4j.io.SAXReader.class-----该类提供了reader方法,可以将xml文件读取为Document对象,该方法返回值类型为Document

2.org.dom4j.Document.class----------该类提供了getRootElement方法,可以获得Document对象的根节点,此方法返回值类型是Element

3.org.dom4j.Element-------该类提供了elements方法,获取所有的子节点,返回值类型为Element;

                attributeValue方法,获得通过属性名节点的属性值,返回值类型为String

                getStringValue()方法,获得element的文本值,返回值类型为String

下面使用上述方法来解析XML文件。

一:新建或者自己导如XML文件。作者为了方便演示,新建一个新的XML文件,如下。

<?xml version="1.0" encoding="UTF-8"?>

<students>
<student id="1">
<name>Claire</name>
<age>18</age>
<gender>女</gender>
</student>
<student id="2">
<name>Leafly</name>
<age>18</age>
<gender>男</gender>
</student>
<student id="3">
<name>Dingdang</name>
<age>18</age>
<gender>男</gender>
</student>
<student id="4">
<name>DingDing</name>
<age>18</age>
<gender>男</gender>
</student>
<student id="5">
<name>DangDang</name>
<age>18</age>
<gender>女</gender>
</student> </students>

2.将上述xml文件放到src下面。

3.创建一个Student类,其属性与上述xml中的元素一致。

public class Student {
//private static final int AAA = 1;
private String id;
private String name;
private String age;
private String gender; //构造 public Student() { } public Student(String id, String name, String age, String gender) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
} //getter setter
public String getId() {
return id;
} public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
} //toString
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
} }

4.创建新类ReadXMl,在该类中创建方法来解析XML文件。

    private static void readXmlFun() throws DocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

        //1.反射,得到类的引用
Class student = Class.forName("readXmlAndReflect.Student");
//通过类的引用,得到类的对象
Object stuInstance = student.newInstance();
//创建一个list 来放多个student的对象
List<Student> students = new ArrayList<Student>(); SAXReader reader = new SAXReader();
//将XML文件读取为一份document对象
Document document = reader.read(readXmlFun.class.getResourceAsStream("/StudentDate.xml"));
//利用Document类中的方法,获取根节点.返回的是Element
Element rootElement = document.getRootElement(); //利用Element中的方法,获取根节点下的全部子节点.返回一个List<element>
List<Element> elements = rootElement.elements(); //利用Element中的方法,获取子 节点中的属性(StudentData中的属性为id)
//1.遍历list,获得每个元素
for (Element element : elements) {
System.out.println("---------------------------------");
//遍历并得到每个元素执行属性名称的属性值
String stuId = element.attributeValue("id");
System.out.println("学生id为"+ stuId);
//遍历并获得每个元素的全部子节点,返回一个List<element>
List<Element> subElement = element.elements(); //通过方法名反射出方法对象
Method method2 = student.getDeclaredMethod("setId", String.class);
//通过反射调用方法,stuInstance对象调用method,参数为stuData---相当于给各参数赋值
method2.invoke(stuInstance, stuId); for (Element subElementData : subElement) {
//得到每个子节点的名字
String elementName = subElementData.getName();
//遍历并获得每个子元素的文本内容,如得到name子节点的文本值为Claire
String stuData = subElementData.getStringValue();
System.out.println(elementName +"为" + stuData); //通过elemetname得到对应的get set方法,先拼接出方法名,比如 name--setName
String funName = "set" + (elementName.charAt(0)+"").toUpperCase()+elementName.substring(1); //通过方法名反射出方法对象
Method method1 = student.getDeclaredMethod(funName, String.class);
//通过反射调用方法,调用stuInstance对象的method方法,参数为stuData---给各属性赋值
method1.invoke(stuInstance, stuData);
}
//将每个学生对象添加到list列表中
students.add((Student)stuInstance);
System.out.println(students); }
}

这里解释下,上面使用的

Document document = reader.read(readXmlFun.class.getResourceAsStream("/StudentDate.xml"));
前面加上/------------代表在当前类的src下面找

如果没有/--------------代表在跟类同级的目录下找。


可以看到上面使用了反射。利用反射可以动态的为每一个Student对象赋值。当我们的XML文件改变,添加或删除了新的属性之后,完全不需要去修改我们的ReadXML类,只在Student类中添加或删除对应的属性即可。实现了解耦。

我们经常通过反射来做下面的事情:

1.获取到某各类的引用

  通常有3种方式:

    1.Class clazz = Class.forName(" 这里必须是类全名");

    2.我们每一个类都有一个静态的class属性:Class clazz =类名A.Class(这个与第一种方式的区别是,不会去运行类A中的静态代码块);

    3.每个类都有一个getClass()方法: classA a = new ClassA(); Class clazz =a.getClass();

2.通过该类的引用获取类的对象

  object o = clazz.newInstance();

3.通过该类的引用获取属性

  

4.通过该类的引用获取所有方法(普通/构造)

下面代码详细说明了反射机制中常用的方法,有兴趣可以了解下:

package readXmlAndReflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Types; public class Reflect {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class clazz = Class.forName("readXmlAndReflect.Student");
//创建对象
Object o =clazz.newInstance(); //创建一个stringBuffer
StringBuffer buffer = new StringBuffer(); //类 public class readXmlAndReflect.Student{}
buffer.append("\n"+"-------------class-------------------"+"\n");
buffer.append(Modifier.toString(clazz.getModifiers()) + " class " + clazz.getName()+"{"+"\n"); //域
buffer.append("\n"+"-------------field-------------------"+"\n");
//获取所有声明的属性,包括私有和常量
Field[] fields = clazz.getDeclaredFields();
//遍历所有的属性
for (Field field : fields) {
//获取属性的修饰符 如public static
buffer.append("\t" + Modifier.toString(field.getModifiers()));
//获取属性的类型 如 string int getType()获取到的类全名(如java.lang.String),想要获得简单类型名如String,可以使用Class类中getSimpleName()方法
buffer.append("\t" + field.getType().getSimpleName());
//获取属性名称
buffer.append("\t" + field.getName());
buffer.append(";"+"\n"); //得到域之后有什么用呢?
//我们可以直接使用得到的域给其赋值或读取域的值,由于域都是私有的,这里需要利用反射打破类的封装
field.setAccessible(true);//如果没有这一句,运行时会报错java.lang.IllegalAccessException:
//给对象0的域field 赋值为"3"
field.set(o, "3");
//获取 对象o 的 域field 的值
System.out.println(field.get(o)); } //方法 如 public static string function(){}
buffer.append("\n"+"-------------function-------------------"+"\n");
//获得所有声明的方法,包括private
Method[] motheds = clazz.getDeclaredMethods(); for (Method method : motheds) {
//获得方法的修饰符 如 public static
buffer.append("\t"+Modifier.toString(method.getModifiers()) + " ");
//获得方法的返回值类型
buffer.append(method.getReturnType().getSimpleName()+" ");
//获得方法名
buffer.append(method.getName() + "(");
//获得方法的参数类型,可能有多个参数,所以返回值为一个数组
Class[] parameterTypes = method.getParameterTypes();
//遍历方法的参数类型
for (Class parameterType : parameterTypes) {
//遍历获得每一个参数类型
buffer.append(parameterType.getSimpleName()+", ");
}
buffer.append(") { }"+"\n"); } //获得方法有什么用??通常用来调用方法
//1.先通过方法名来获得一个方法
Method setNameFun = clazz.getMethod("setName", String.class);
//可以直接调用,调用方法method---调用o对象的setNameFun方法,参数为“小笨蛋”
setNameFun.invoke(o, "小笨蛋"); //构造方法
buffer.append("\n" + "-------------constructions-------------------"+"\n");
Constructor[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) { buffer.append(Modifier.toString(constructor.getModifiers()) + " ");
buffer.append(constructor.getName() + " (");
Class[] parametertypes = constructor.getParameterTypes();
for (Class parametertype : parametertypes) {
buffer.append(parametertype.getSimpleName() +",");
}
buffer.append(") { }"+"\n");
} buffer.append("}"); System.out.println(buffer);
} }

java---解析XML文件,通过反射动态将XML内容封装到一个类中的更多相关文章

  1. XML解析之sax解析案例(一)读取contact.xml文件,完整输出文档内容

    一.新建Demo2类: import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXPar ...

  2. Java解析JSON文件的方法

    http://blog.sina.com.cn/s/blog_628cc2b70101dydc.html java读取文件的方法 http://www.cnblogs.com/lovebread/ar ...

  3. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  4. Java反射机制demo(四)—获取一个类的父类和实现的接口

    Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...

  5. Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

    Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

  6. Java中是否可以调用一个类中的main方法?

    前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...

  7. java解析properties文件

    在自动化测试过程中,经常会有一些公用的属性要配置,以便后面给脚本使用,我们可以选择xml, excel或者json格式来存贮这些数据,但其实java本身就提供了properties类来处理proper ...

  8. 【转】java 解析 plist文件

    为了方便的将spritesheet的图导入我自己的动画编辑器!我做了plist文件解析DOM解析比较麻烦 因为element getChildNodes 会获取到text对象.而这个对象可能是一个空白 ...

  9. Spring如何解析XML文件——Spring源码之XML初解析

    首先,在我的这篇博客中已经说到容器是怎么初步实现的,并且要使用XmlBeanDefinitionReader对象对Xml文件进行解析,那么Xml文件是如何进行解析的,将在这片博客中进行一些陈述. 数据 ...

随机推荐

  1. 过拟合是什么?如何解决过拟合?l1、l2怎么解决过拟合

    1. 过拟合是什么? https://www.zhihu.com/question/264909622    那个英文回答就是说h1.h2属于同一个集合,实际情况是h2比h1错误率低,你用h1来训练, ...

  2. HttpHandler使用Session

    继承自IHttpHandler的类要实现两个接口:ProcessRequest和IsReusable但还不能使用Session,要使用Session需要下面的步骤处理: 1.先引用System.Web ...

  3. 1..net转java背景介绍

    注册博客2年了.从注册就开始接触.net.以前也有想过转java.只是没想过会这么快. .net语法这么优美好用.可惜了生态环境. .net还没有学成大神.就要离开了. 公司有个项目要用java.在加 ...

  4. AngularJS显示一个简单表格

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. triplet loss

    因为待遇低,因为工作不开心,已经严重影响了自己的工作积极性和工作效率,这几天发觉这样对自己实在是一种损失,决定提高工作效率,减少工作时间. 说说最近做的tracking, multi-object t ...

  6. ProjectServer任务审批后自动发布

    我们知道ProjectServer汇报工时的顺序是这样: 1.项目成员打开自己的时间表,选择要汇报的任务,在汇报工时栏填写实际工时. 2.汇报工时后点击保存. 3.将汇报工时的任务提交给项目经理. 4 ...

  7. 嗨翻C语言笔记(二)

    ~a a中所有位都取反 a & b a中的位 与 b中的位 (都为1则1,否则为0) a | b a中的位 或 b中的位 (只要对应位一个位1则为1) a ^ b a中的位 亦或 b中的位 & ...

  8. Java分享笔记:RandomAccessFile流 & 在文件指定位置插入内容

    RandomAccessFile流:随机存取文件流,该类定义了一个记录指针,通过移动指针可以访问文件的任意位置,且对文件既可以读也可以写.使用该类的write方法对文件写入时,实际上是一种覆盖效果,即 ...

  9. python中的"is"与"=="比较

    在 Python 中会用到对象之间比较,可以用 ==,也可以用 is .但是它们的区别是什么呢? is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同.莱布尼茨说过: ...

  10. Ubuntu 16.04 swoole扩展安装注意!!!

    前言:目前很多项目估计常常会用到swoole扩展,如个人使用Ubuntu虚拟机安装扩展,这里总结一下遇到的问题: 一.先保证服务器时间同步当前地区时间,如北京时间: 1.设定时区 如:设定时区:dpk ...