java详解 --- Dom4j解析XML文档
2018-01-09 21:54
447 查看
dom4j是一个简单的开源库 , 用于处理XML , XPath和XSLT , 它基于Java平台 , 使用Java的集合框架 , 全面集成了DOM , SAX和JAXP , 今天主要说说dom4j解析xml文件.
原因:xml文档是用来存放数据的 , 这些数据需要被程序传递 并 使用 , 但是xml文档的语法和使用它的语言的语法规则不同 , 所以需要根据使用它语法的语法规则 和 xml文档规则将xml文档存储的数据转换成想使用它语言能使用的数据 , 这个过程就叫做xml文档解析
2.应用
因为xml文档在各语言基础上定义一致 , 并且解析逻辑一致 , 所以用于各语言之间的数据转换
3.xml常用的解析规则
1).DOM - document
DOM是面向文档结构树的对象模型解析
优点:可以清晰的展示节点的层次关系 和 连带关系 , 具有强大的节点操作功能
缺点:该方式会将整个文档解析的DOM树整体存放在内存中 , 不利于大型文档的操作
2).SAX - simple api for xml
SAX是面向文档接口的逻辑模型解析
优点:具有快速处理xml文档的能力 , 节约内存空间(根据需求进行必要的局部解析 且 前后解析具有很大的灵活性)
缺点:无法标注节点之间的层次关系 , 节点功能操作单一化
3).Dom4j
整合了各种语法解析的优点 具有灵活的DOM文档树的内存印象
1).步骤
① 通过SAXReader()空控制器方法生成操作XML文档的输出流
② 通过读取操作 与文件 或 流 建立起直接关系
2).Dom4j文档解析的数据操作
2.利用Dom4j将xml解析为对象形式
既然是对象形式,首先创建三个类:
School类 Teacher类 Student类
main方法:
首先创建一个xml文件:取名为School.xml <?xml version="1.0" encoding="utf-8"?> <School value="老师+学生"> <!-- CDATA语法:该语法规定语法内的文字为XML语法不解析的内容 CDATA语法内的内容为纯文本 --> <![CDATA[ <省重点>民办高级小学 ]]> 学校 <Teachers name="老师"> <Teacher id="001"> <name>T1</name> <gender>男</gender> <subject>艺术</subject> <salary>800/天</salary> </Teacher> <Teacher id="002"> <name>T2</name> <gender>女</gender> <subject>美术</subject> <salary>500/天</salary> </Teacher> <Teacher id="003"> <name>T3</name> <gender>男</gender> <subject>生物</subject> <salary>1000/天</salary> </Teacher> </Teachers> <Students name="学生"> <Student id="01"> <name>S1</name> <gender>男</gender> <class>三班</class> </Student> <Student id="02"> <name>S2</name> <gender>女</gender> <class>五班</class> </Student> <Student id="03"> <name>S3</name> <gender>男</gender> <class>一班</class> fcee </Student> </Students> </School>
一.XML文档的解析
1.为什么要解析XML文档?原因:xml文档是用来存放数据的 , 这些数据需要被程序传递 并 使用 , 但是xml文档的语法和使用它的语言的语法规则不同 , 所以需要根据使用它语法的语法规则 和 xml文档规则将xml文档存储的数据转换成想使用它语言能使用的数据 , 这个过程就叫做xml文档解析
2.应用
因为xml文档在各语言基础上定义一致 , 并且解析逻辑一致 , 所以用于各语言之间的数据转换
3.xml常用的解析规则
1).DOM - document
DOM是面向文档结构树的对象模型解析
优点:可以清晰的展示节点的层次关系 和 连带关系 , 具有强大的节点操作功能
缺点:该方式会将整个文档解析的DOM树整体存放在内存中 , 不利于大型文档的操作
2).SAX - simple api for xml
SAX是面向文档接口的逻辑模型解析
优点:具有快速处理xml文档的能力 , 节约内存空间(根据需求进行必要的局部解析 且 前后解析具有很大的灵活性)
缺点:无法标注节点之间的层次关系 , 节点功能操作单一化
3).Dom4j
整合了各种语法解析的优点 具有灵活的DOM文档树的内存印象
二.Dom4j解析文档
1.Dom4j解析文档1).步骤
① 通过SAXReader()空控制器方法生成操作XML文档的输出流
② 通过读取操作 与文件 或 流 建立起直接关系
public static void main(String[] args) throws Exception { // Dom4j解析文档 SAXReader reader = new SAXReader(); String path = SD.getPath(SD.d_s , "lesson" , "xml"); File file = new File(path, "School.xml"); Document doc = reader.read(file); System.out.println(doc); }
2).Dom4j文档解析的数据操作
// Dom4j文档解析的操作 SAXReader reader = new SAXReader(); String path = SD.getPath(SD.d_s , "lesson" , "xml"); File file = new File(path , "School.xml"); Document doc = reader.read(file); // 1. 数据相关操作 // ① 获取根节点 Element root = doc.getRootElement(); // ② 获取节点的内容 // 保留数据中的空格文本 String tTxt = root.getText(); // 将数据中的空格做最简处理 String tTxtr = root.getTextTrim(); System.out.println("② " + tTxt); System.out.println("② " + tTxtr); // ③ 获取节点属性 // 获取属性的个数 System.out.println("③.属性个数为: " + root.attributeCount()); // 根据索引获取对应节点属性 Attribute attr = root.attribute(0); // 根据key值获取对应属性 // Attribute attr = root.attribute("value"); System.out.println("③ " + attr); // ④ 获取节点属性值 String key = attr.getName(); String value = attr.getValue(); System.out.println("④ " + key + ": " + value); // 2.节点相关操作 // 获取子节点 List<Element> list = root.elements(); for (Element element : list) { // ⑤ 节点名 System.out.println("⑤ " + element.getName()); } // ⑥ 获取指定节点 Element Teacher = root.element("Teachers"); System.out.println("⑥ " + Teacher.getName()); // ⑦ 获取父节点 Element parent = Teacher.getParent(); // 判断是否与根节点相同 System.out.println("⑦ " + (parent == root));
三.利用Dom4j将xml解析为集合形式和对象形式
1.利用Dom4j将xml解析为集合形式// 将xml文档解析成 集合 形式 String path = SD.getPath(SD.d_s , "lesson" , "xml"); File file = new File(path , "School.xml"); SAXReader reader = new SAXReader(); Document document = reader.read(file); // 获取School节点 Element root = document.getRootElement(); // Students / Teachers 的节点 Element teas = root.element("Teachers"); Element stus = root.element("Students"); // 获取Students / Teachers的子节点们 List<Element> ts = teas.elements(); List<Element> ss = stus.elements(); // 获取存放老师们的Collection Collection<Map<String, String>> tColl = new ArrayList<>(); // 获取老师的具体数据 // t --> Teacher * 3 for (Element t : ts) { // 获取存放老师信息的Map集合 Map<String, String> tMap = new HashMap<>(); // id是特殊属性 需特殊操作 tMap.put("id", t.attributeValue("id")); // 遍历Teacher所有子节点 遍历过程中循环操作节点 及 节点数据 for (Object ele : t.elements()) { // e -> name / gender / subject / salary Element e = (Element)ele; // key:代表标签名 value:代表标签值 tMap.put(e.getName(), e.getText()); } tColl.add(tMap); } // 获取存放学生的Collection Collection<Map<String,String>> sColl = new ArrayList<>(); // 获取学生的具体数据 // s -> Student * 4 for (Element s : ss) { // 获取存放学生的map Map<String, String> sMap = new HashMap<>(); // Num是特殊属性 需特殊操作 sMap.put("Num", s.attributeValue("Num")); for (Object ele : s.elements()) { Element e = (Element)ele; sMap.put(e.getName(), e.getText()); } sColl.add(sMap); } // 获取学校School总集合 Collection<Map<String, Collection<Map<String, String>>>> S = new ArrayList<>(); // 获取老师们 和 学生们的map总集合 Map<String, Collection<Map<String, String>>> tsMap = new HashMap<>(); Map<String, Collection<Map<String, String>>> ssMap = new HashMap<>(); tsMap.put("Teachers", tColl); ssMap.put("Students", sColl); S.add(tsMap); S.add(ssMap); System.out.println(S);
2.利用Dom4j将xml解析为对象形式
既然是对象形式,首先创建三个类:
School类 Teacher类 Student类
// 学校类 class School{ private String msg; private Collection<Teacher> teachers; private Collection<Student> students; public String Msg() { return msg; } public void setMsg(String msg) { this.msg = msg; } // 问题一:在getter方法期间 应该将teachers / students 处理完毕 // 解决:在构造School的类对象时 处理teachers / students public School() { this.teachers = new ArrayList<>(); this.students = new ArrayList<>(); } // 问题二:如何做到对外接口为添加单一 老师 / 学生 // 按照功能性设计setter方法 public void setTeacher(Teacher t) { this.teachers.add(t); } public void setStudents(Student s) { this.students.add(s); } // 问题三:如何设计getter方法 /* * 解决:数据解析的最终目的 是使用解析到的数据 * 因此如何最方便直接的得到 就如何设计getter方法 */ // 老师的getter方法 public Collection<Teacher> Teacher(){ return teachers; } public Teacher getTeacher(int index) { if (index >= teachers.size()) { return null; } return ((ArrayList<Teacher>)teachers).get(index); } // 学生的getter方法 public Collection<Student> students(){ return students; } public Student getStudent(int index) { if (index >= students.size()) { return null; } return ((ArrayList<Student>) students).get(index); } // 重写toString方法 @Override public String toString() { return "School [msg=" + msg + ", teachers=" + teachers + ", students=" + students + "]"; } } // 老师类 class Teacher{ private String id; private String name; private String gender; private String subject; private String salary; // set / get 方法 // setName / getName | Name都可以 public String ID() { return id; } public void setID(String iD) { this.id = iD; } public String Name() { return name; } public void setName(String name) { this.name = name; } public String Gender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String Subject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String Salary() { return salary; } public void setSalary(String salary) { this.salary = salary; } // 重写toString方法 @Override public String toString() { return "Teacher [ID=" + id + ", name=" + name + ", gender=" + gender + ", subject=" + subject + ", salary=" + salary + "]"; } } // 学生类 class Student{ private String num; private String name; private String gender; private String clazz; // set / get 方法 public String Num() { return num; } public void setNum(String num) { this.num = num; } public String Name() { return name; } public void setName(String name) { this.name = name; } public String Gender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String Clazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } // 重写toString方法 @Override public String toString() { return "Student [Num=" + num + ", name=" + name + ", gender=" + gender + ", clazz=" + clazz + "]"; } }
main方法:
// 使用解析后的结果 private static void useResult(School school) { System.out.println(school); // 获取所有学生的信息 Collection<Student> stus = school.Students(); System.out.println(stus); // 获取第三个学生 Student stu = school.getStudent(2); System.out.println(stu); // 获取第一个学生的班级 String clazz = school.getStudent(0).Clazz(); System.out.println(clazz); } public static void main(String[] args) throws Exception{ // 将xml文档解析成 单一对象 形式 // 最终结果 School school = new School(); // 解析数据 SAXReader reader = new SAXReader(); String path = SD.getPath(SD.d_s , "lesson" , "xml"); File file = new File(path, "School.xml"); Document document = reader.read(file); // 获取根节点 Element root = document.getRootElement(); // root.elements() -- School所有的子节点 for (Object object : root.elements()) { // (Element)object --> Teachers / Students analyseObject((Element)object , school); } school.setMsg(root.getTextTrim()); // 打印结果 System.out.println(school); } // 参数element -- Teachers / Students private static void analyseObject(Element element , School school) { // element.elements() --> Teachers / Students的所有子节点 for (Object obj : element.elements()) { // ele --> Teacher节点 * 3 / Student节点 *4 Element ele = (Element)obj; // 如果ele为Teacher -- analyseTeacher // 如果ele为Student -- analyseStudent if (ele.getName().equals("Teacher")) { Teacher t = analyseTeacher(ele); school.setTeacher(t); } if (ele.getName().equals("Student")) { school.setStudents(analyseStudent(ele)); } } } //参数ele -- Teacher节点 private static Teacher analyseTeacher(Element ele) { Teacher t = new Teacher(); // id为特殊节点 特殊处理 t.setID(ele.attributeValue("id")); // name / gender / subject / salary t.setName(ele.element("name").getText()); t.setGender(ele.element("gender").getText()); t.setSubject(ele.element("subject").getText()); t.setSalary(ele.element("salary").getText()); return t; } // 参数ele -- Student节点 private static Student analyseStudent(Element ele) { Student s = new Student(); // Num 通过属性进行设置 s.setNum(ele.attributeValue("num")); // name / gender / class -- 通过子标签进行设置 s.setName(ele.element("name").getText()); s.setGender(ele.element("gender").getText()); s.setClazz(ele.element("class").getText()); return s; }
相关文章推荐
- 【Java编程】Dom4j解析和生成XML文档
- java中利用Dom4j解析和生成XML文档
- JAVA解析XML的方式DOM、SAX、DOM4J、JDOM、StAX之详解与比较
- java中dom4j解析xml生成xml文档,dom4j工具压缩包原代码
- java的xml学习[DOM4J方式解析XML文档]
- JAVA解析XML的方式DOM、SAX、DOM4J、JDOM、StAX之详解与比较
- Java对XML文档进行解析(dom4j解析)
- Java——使用DOM4j解析XML文档
- java--DOM4j-SAXReader对xml文档的解析2
- java 中dom4j 解析xml文档
- 【XML解析】(4)Java下使用DOM4J解析方式对XML文档进行解析
- JavaWeb 之 XML文档的DOM和SAX解析方式详解
- java与xml之DOM4J生成和解析XML文档
- java-Dom4j解析XML详解
- java中利用dom4j对XML文档的创建、解析、查找、修改、保存等操作。
- [Java开发之路](12)JDOM和DOM4J解析XML文档
- java中利用dom4j对XML文档的创建、解析、查找、修改、保存等操作。
- JavaWeb 之 XML文档的DOM和SAX解析方式详解
- java--DOM4j-SAXReader对xml文档的解析2
- Java解析XML文档的四种方法详解