需求描述
很多时候我们在项目中会遇到读取xml文件的需求,遇到标准的xml还好,随便引入一个开源工具包就能解决。但是会存在这样的问题:
- 一个很小的功能,不常用,为此需要引入一个额外的开源包?
- xml文件内容很不规范,或者说随时可能会根据需求不停地变动!
这时候,我们就想用Java本身自己的jdk库去解决这个问题,今天我将给大家带来一个简单又快捷的自定义规则读取xml文件内容,包括节点内容和属性哦!
xml自定义内容
<school> <class value="1"> <studend name="Lisa" math="145" english="120" chinese="110"/> <studend name="Alex" math="115" english="110" chinese="110"/> <studend name="Leo" math="145" english="124" chinese="110"/> </class> <class value="2"> <studend name="Lisa" math="90" english="120" chinese="110"/> <studend name="Alex" math="122" english="120" chinese="94"/> <studend name="Jack" math="89" english="120" chinese="110"/> <studend name="Leo" math="99" english="120" chinese="110"/> </class> </school>
学校school下面有很多个班级class,班级class下面有很多个学生student,学生student有一些课程成绩,语数外。
直接上Java代码
解决方案
首先我们来定义一个自主规则的handler和一些数据类
public class MyStudent { private double math; private double english; private double chinese; // 构造函数和getter,setter ... } public class MyClass { private int classNo; private List<MyStudent> students; // 构造函数和getter,setter ... }
重点来了,这个handler规则可以自己定义,很好理解:
public class MyHandler extends DefaultHandler { private final List<MyClass> classList = new LinkedList<>();//这里是最终的结果,存放班级 private MyClass myClass = null; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if (qName.equals("class")) { // 当读取到班级节点的时候 myClass = new MyClass(); String classNo = attributes.getValue("value");// 拿取属性 myClass.setClassNo(Integer.parseInt(classNo)); } else if (qName.equals("student")) { //当读取到学生节点的时候 String math = attributes.getValue("math"); String english = attributes.getValue("english"); String chinese = attributes.getValue("chinese"); MyStudent student = new MyStudent(); student.setChinese(Double.parseDouble(chinese)); student.setEnglish(Double.parseDouble(english)); student.setMath(Double.parseDouble(math)); myClass.getStudents().add(student); // 加入到结果中 } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if (qName.equals("class")) { //当班级节点读取完成 classList.add(myClass); myClass = null; //记得清理数据 } } public List<MyClass> getClassList() { //留个口子返回数据 return classList; } }
然后使用也非常简单:
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); MyHandler handler = new MyHandler(); saxParserFactory.newSAXParser().parse("xmlPath", handler); handler.getClassList(); // 这就是转换好的结果啦
结束啦,到这里你想要的xml结果集合就已经转换成功并且拿到啦!
收工。