xml的常見四種解析方式
xml的概念:
XML(EXtensible Markup Language),可擴充套件標記語言,一種資料的交換格式。它的平臺無關性、語言無關性、系統無關性
給資料的整合、儲存和互動帶來了極大的方便。在不同的語言中它的解析方式是一樣的,只是語法不一樣。
xml和html的的差別:
XML 被設計用來傳輸和儲存資料。
HTML 被設計用來顯示資料。
以下書寫一個school.xml為例用四種不同的方法來解析:
shcool.xml
<?xml version="1.0" encoding="UTF-8"?> <school id="先鋒學院"> <classes id="java001班"> <sudent id="001"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="001"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="002"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> </classes> <classes id="java002班"> <sudent id="001"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="004"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> </classes> <classes id="java003班"> <sudent id="001"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="002"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="003"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> </classes> <classes id="java004班"> <sudent id="004"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> <sudent id="002"> <name>張三</name> <age>13</age> <gender>男</gender> </sudent> </classes> </school>
javabeen文件
student.java
package domain; public class Student { private String id; private String name ; private int age; private String gender; public Student() {} public Student(String id, String name, int age, String gender) { this.id = id; this.name = name; this.age = age; this.gender = gender; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", age=" + age + ", gender=" + gender + "]"; } }
classes.java
package domain; import java.util.ArrayList; public class Classes { private String id; ArrayList<Student> sArrayList; public Classes() {} public String getId() { return id; } public void setId(String id) { this.id = id; } public ArrayList<Student> getsArrayList() { return sArrayList; } public void setsArrayList(ArrayList<Student> sArrayList) { this.sArrayList = sArrayList; } }
school.java
package domain;
import java.util.ArrayList;
public class School {
private String name;//學校名稱
ArrayList<Classes> aClasses ;
public School(){};
public School(String name, ArrayList<Classes> aClasses) {
this.name = name;
this.aClasses = aClasses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Classes> getaClasses() {
return aClasses;
}
public void setaClasses(ArrayList<Classes> aClasses) {
this.aClasses = aClasses;
}
}
一、DOM解析:
DOM(java自帶的解析jar包):xml的本質是一種分層結構而dom介面提供了一種通過分層物件模型來訪問XML文件資訊的方式,這些分層物件模型依據XML的文件結構形成了一棵節點樹。無論xml檔案中描述的是什麼樣的型別資訊,dom都以節點樹的形式去進行解析。當DOM對xml檔案進行解析時會把xml文件轉化成DOM樹放在記憶體中,所以當xml文件過於大是對記憶體的需求是比較高的。但是由於DOM分析器所採用的樹結構的思想與XML文件的結構相吻合,同時鑑於隨機訪問所帶來的方便。
優點:
- 形成了樹的結構,容易理解,程式碼更好編寫
- 解析過程中,樹結構存在記憶體中方便修改
缺點:
- 形成可樹結構把文件全部載入進了記憶體,對記憶體的消耗較大
- 如果xml文件較大(>10M)時,會造成記憶體溢位
DOM解析程式碼:
package xml;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import domain.Classes;
import domain.School;
import domain.Student;
//DOM解析school
public class XmlStudent {
public static void main(String[] args) throws Exception {
// 獲取一個檔案工廠例項
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
// 通過文件工廠獲取解析器物件
DocumentBuilder documentBuilder = dbFactory.newDocumentBuilder();
// 獲取文件路徑
Document parse = documentBuilder.parse("src/School.xml");
// 獲取xml文件
Element SchoolElement = parse.getDocumentElement();
String schoolname = SchoolElement.getAttribute("id");
System.out.println(schoolname);
// 建立School物件
School school = new School();
school.setName(schoolname);
ArrayList<Classes> classesList = new ArrayList<Classes>();
// 獲取school中的直接子節點
NodeList childNodes = SchoolElement.getChildNodes();
// 使用for迴圈遍歷school節點中的子節點(class)
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == 1) {
Element classElement = (Element) node;
String classId = classElement.getAttribute("id");
// 建立一個calss例項
Classes classes = new Classes();
classes.setId(classId);
// 建立一個List集合用於儲存student
ArrayList<Student> studentList = new ArrayList<Student>();
// 獲取class類的直接子節點
NodeList childNodes1 = classElement.getChildNodes();
// 使用for迴圈遍歷school中的所有子節點
for (int j = 0; j < childNodes1.getLength(); j++) {
Node node1 = childNodes1.item(j);
if (node1.getNodeType() == 1) {
Element studentElement = (Element) node1;
String studentId = studentElement.getAttribute("id");
// 建立一個Student例項
Student student = new Student();
student.setId(studentId);
// 獲取student節點中各個節點的屬性值
String studentName = studentElement
.getElementsByTagName("name").item(0)
.getTextContent();
String studentAge = studentElement
.getElementsByTagName("age").item(0)
.getTextContent();
String studentGender = studentElement
.getElementsByTagName("gender").item(0)
.getTextContent();
student.setName(studentName);
student.setAge(Integer.parseInt(studentAge));
student.setGender(studentGender);
// 建立student集合將所有的student類存放到ArrayList集合中
studentList.add(student);
}
}
// 完成Classes類的初始化
classes.setsArrayList(studentList);
classesList.add(classes);
}
}
school.setaClasses(classesList);
// 遍歷school裡面的物件資訊,並且將所有的student和class資訊打印出來
System.out.println("學校名稱:" + school.getName());
System.out.println("----------------------------------");
ArrayList<Classes> getaClasses = school.getaClasses();
Iterator<Classes> iterator = getaClasses.iterator();
while (iterator.hasNext()) {
Classes classes = iterator.next();
System.out.println("班級名稱:" +classes.getId());
Iterator<Student> iterator2 = classes.getsArrayList()
.iterator();
while (iterator2.hasNext()) {
Student student = iterator2.next();
System.out.println(student.toString());
}
System.out.println("--------");
}
}
}
二、SAX
SAX的全稱是Simple APIs for XML,也即XML簡單應用程式介面。與DOM不同,SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML資料的方式。當使用SAX分析器對XML文件進行分析時,會觸發一系列事件,並激活相應的事件處理函式,應用程式通過這些事件處理函式實現對XML文件的訪問,因而SAX介面也被稱作事件驅動介面。
優點
- 採用事件驅動模式,對記憶體耗費比較小。
- 適用於只處理XML檔案中的資料時。
缺點
- 編碼比較麻煩。
- 很難同時訪問XML檔案中的多處不同資料。
程式碼:
三、JDOM
特點:
程式碼:
- 僅適用具體的類,不使用介面
- 使用了大量的collections
四、dom4j
特點:
1、JDOM的一種智慧分支,它合併了許多超出基本XML文件表示的功能。
2、它使用介面和抽象基本類方法。
3、具有效能優異、靈活性好、功能強大和極端易用的特點。
4、是一個開放原始碼的檔案
package xml;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import domain.copy.Classes;
import domain.copy.School;
import domain.copy.Student;
public class ParsStudentXml {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
// 建立一個student集合
ArrayList<Student> studentArrList = new ArrayList<Student>();
// 建立一個Sax解析器物件
SAXReader saxReader = new SAXReader();
// 使用解析器讀取xml檔案
Document document = saxReader.read("src/school.xml");
Element rootElement = document.getRootElement();
// 獲取根節點的屬性
String schoolId = rootElement.attributeValue("id");
School school = new School();
school.setName(schoolId);
// 通過根節點獲取所有的子節點物件
List<Element> classElements = rootElement.elements();
// 遍歷班級集合
for (Element classElement : classElements) {
String classId = classElement.attributeValue("id");
Classes classes = new Classes();
classes.setId(classId);
classes.setSchool(school);
// 根據班級節點獲取所有的直接子節點
List<Element> studentList = classElement.elements();
for (Element studentElements : studentList) {
String studentId = studentElements.attributeValue("id");
Student student = new Student();
student.setId(studentId);
String studentName = studentElements.element("name").getText();
String studentAge = studentElements.element("age").getText();
String studentGender = studentElements.element("gender")
.getText();
student.setName(studentName);
student.setAge(Integer.parseInt(studentAge));
student.setGender(studentGender);
student.setClasses(classes);
studentArrList.add(student);
}
}
Iterator<Student> iterator = studentArrList.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student.toString());
}
}
}
程式碼