当前位置: 首页>编程语言>正文

java 动态设置xml java动态解析xml

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

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

java 动态设置xml java动态解析xml,java 动态设置xml java动态解析xml_XML,第1张

引入成功后,来简单了解该包提供的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文件,如下。

Claire

18

Leafly

18

Dingdang

18

DingDing

18

DangDang

18

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

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

public classStudent {//private static final int AAA = 1;
privateString id;privateString name;privateString age;privateString gender;//构造
publicStudent() {
}publicStudent(String id, String name, String age, String gender) {super();this.id =id;this.name =name;this.age =age;this.gender =gender;
}//getter setter
publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getAge() {returnage;
}public voidsetAge(String age) {this.age =age;
}publicString getGender() {returngender;
}public voidsetGender(String gender) {this.gender =gender;
}//toString
@OverridepublicString toString() {return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
}

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

private static void readXmlFun() throwsDocumentException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {//1.反射,得到类的引用

Class student = Class.forName("readXmlAndReflect.Student");//通过类的引用,得到类的对象

Object stuInstance =student.newInstance();//创建一个list 来放多个student的对象

List students = new ArrayList();

SAXReader reader= newSAXReader();//将XML文件读取为一份document对象

Document document = reader.read(readXmlFun.class.getResourceAsStream("/StudentDate.xml"));//利用Document类中的方法,获取根节点.返回的是Element

Element rootElement =document.getRootElement();//利用Element中的方法,获取根节点下的全部子节点.返回一个List

List 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

List 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下面找

java 动态设置xml java动态解析xml,java 动态设置xml java动态解析xml_java_02,第2张

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

java 动态设置xml java动态解析xml,java 动态设置xml java动态解析xml_java_03,第3张

可以看到上面使用了反射。利用反射可以动态的为每一个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.通过该类的引用获取所有方法(普通/构造)

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

packagereadXmlAndReflect;importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjava.lang.reflect.Modifier;importjava.sql.Types;public classReflect {public static void main(String[] args) throwsClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

Class clazz= Class.forName("readXmlAndReflect.Student");//创建对象

Object o =clazz.newInstance();//创建一个stringBuffer

StringBuffer buffer = newStringBuffer();//类 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);

}

}


https://www.xamrdz.com/lan/5by1923080.html

相关文章: