1. 程式人生 > >xml的常見四種解析方式

xml的常見四種解析方式

xml的概念:

XMLEXtensible 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文件的結構相吻合,同時鑑於隨機訪問所帶來的方便。

優點:

  1. 形成了樹的結構,容易理解,程式碼更好編寫
  2. 解析過程中,樹結構存在記憶體中方便修改

缺點:

  1. 形成可樹結構把文件全部載入進了記憶體,對記憶體的消耗較大
  2. 如果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介面也被稱作事件驅動介面。

 優點

  1. 採用事件驅動模式,對記憶體耗費比較小。
  2. 適用於只處理XML檔案中的資料時。

缺點

  1. 編碼比較麻煩。
  2.  很難同時訪問XML檔案中的多處不同資料。

程式碼: 

三、JDOM

特點:

程式碼: 

  1. 僅適用具體的類,不使用介面
  2. 使用了大量的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());
		}
	}
}

程式碼