【Java 強化】單元測試(JUnit3、JUnit4)、XML(語法、約束、文檔結構)、DOM、DOM4J

Java筆記目錄可以點這裏: Java強化筆記

軟件測試

有一句話這麼說:優秀的軟件不是開發出來的,而是測試出來的。

軟件測試可分爲:黑盒測試白盒測試

黑盒測試:軟件測試工程師

黑盒測試也稱功能測試,它是通過測試來檢測每個功能是否都能正常使用。

在測試中,把程序看作一個不能打開的黑盒子,在完全不考慮程序內部結構和內部特性的情況下,在程序接口進行測試,它只檢查程序功能是否按照需求規格說明書的規定正常使用,程序是否能適當地接收輸入數據而產生正確的輸出信息。

黑盒測試着眼於程序外部結構,不考慮內部邏輯結構,主要針對軟件界面和軟件功能進行測試

黑盒測試是以用戶的角度,從輸入數據與輸出數據的對應關係出發進行測試的。
很明顯,如果外部特性本身設計有問題或規格說明的規定有誤,用黑盒測試方法是發現不了的。

作用:黑盒測試法注重於測試軟件的功能需求,主要試圖發現下列幾類錯誤。

  • 功能不正確或遺漏;
  • 界面錯誤;
  • 輸入和輸出錯誤;
  • 數據庫訪問錯誤;
  • 性能錯誤;
  • 初始化和終止錯誤等。

白盒測試:軟件開發工程師

白盒測試又稱結構測試透明盒測試邏輯驅動測試基於代碼的測試

它是按照程序內部的結構測試程序,通過測試來檢測產品內部動作是否按照設計規格說明書的規定正常進行,檢驗程序中的每條通路是否都能按預定要求正確工作。 這一方法是把測試對象看作一個打開的盒子,測試人員依據程序內部邏輯結構相關信息,設計或選擇測試用例,對程序所有邏輯路徑進行測試,通過在不同點檢查程序的狀態,確定實際的狀態是否與預期的狀態一致。

白盒測試是一種測試用例設計方法,盒子指的是被測試的軟件,白盒指的是盒子是可視的,你清楚盒子內部的東西以及裏面是如何運作的

"白盒"法全面瞭解程序內部邏輯結構、對所有邏輯路徑進行測試。測試者必須檢查程序的內部結構,從檢查程序的邏輯着手,得出測試數據。

單元測試(JUnit3、JUnit4)

單元測試屬於白盒測試。

在你不知道如何測試代碼前,就不要寫代碼去完成功能 —> 測試先行

Java的單元測試:Junit 目前存在三個版本

  1. junit3.x:針對於Java5 之前的版本,沒有註解,得按照規範來寫測試。
  2. junit4.x:針對於Java5 以後的版本,使用註解
  3. junit5.x:針對於 Java8 以後的版本。

我們這裏就是對單元測試有個簡單認識,會簡單利用 3 和 4 編寫一些測試代碼。

測試環境搭建:將 junit 的測試 jar,添加到該項目中。
在這裏插入圖片描述

使用 junit3.x(瞭解)

junit3.x 是 Java5 以前的測試方式。

測試步驟:

  1. 把 junit3.x 的測試 jar,添加到項目中;
  2. 定義一個測試類,並讓該測試類繼承 TestCase
    測試類的名字:XxxTestXxx 表示一個對象或者一個模塊、組件。
  3. EmployeeDAOTest 中編寫測試方法;
    方法是 public 修飾,無返回值無參數的。
    必須以 test 作爲方法的前綴,Xxx 表示測試的功能名字。
public void testXxx() throws Exception {}
  1. 選擇某一個測試方法,鼠標右鍵選擇 [run as junit]
    或者選中測試類,表示測試該類中所有的測試方法。
  • 若要在測試方法之前做準備操作:
    EmployeeDAOTest 覆寫 TestCaseprotected void setUp() throws Exception 方法;
  • 若要在測試方法之後做回收操作:
    EmployeeDAOTest 覆寫 TestCaseprotected void tearDown() throws Exception 方法;
  • 測試執行順序: setUp -> 測試方法 -> tearDown -> setUp -> 測試方法2 -> tearDown

示例:利用 JUnit3 編寫 EmployeeDAOTest 的測試類。

package com.yusael._01_junit.junit3;

import junit.framework.TestCase;

// EmployeeDAO組件的測試類
public class EmployeeDAOTest extends TestCase {
	@Override // 初始化操作
	protected void setUp() throws Exception {
		System.out.println("初始化操作");
	}
	@Override // 銷燬操作
	protected void tearDown() throws Exception {
		System.out.println("銷燬操作");
	}
	// 測試員工的保存操作
	public void testSave() throws Exception {
		System.out.println("保存測試");
	}
	// 測試員工的刪除操作
	public void testDelete() throws Exception {
		System.out.println("刪除測試");
	}
}

在這裏插入圖片描述

使用 junit4.x(掌握)

junit4.x 基於 Java5 開始的版本,支持註解

步驟:

  1. 把 junit4.x 的測試 jar,添加到項目中;;
  2. 定義一個測試類。(不再繼承 TestCase 類)
    測試類的名字: XxxTest
  3. EmployeeDAOTest 中編寫測試方法;
    方法是 public 修飾的,無返回的
    該方法上必須貼有 @Test 標籤,Xxx 表示測試的功能名字。
@Test
public void testXxx() throws Exception {}
  1. 選擇某一個測試方法,鼠標右鍵選擇 [run as junit]
    或者選中測試類,表示測試該類中所有的測試方法。

以後單元測試使用最多的方式:

  • 若要在測試方法之前做準備操作:
    EmployeeDAOTest 隨意定義一個方法並使用 @Before 標註;
    每次執行測試方法之前都會執行 @Before 標註的方法
@Before
public void xx() throws Exception {}
  • 若要在測試方法之後做回收操作:
    EmployeeDAOTest 隨意定義一個方法並使用 @After 標註;
    每次執行測試方法之後都會執行 @After 標註的方法;
@After
public void xx() throws Exception {}
  • 有沒有方式只初始化一次,和最終只銷毀一次呢?
    @BeforeClass 標籤:在所有的 Before 方法之前執行,只在最初執行一次, 只能修飾靜態方法
    @AfterClass 標籤:在所有的 After 方法之後執行,只在最後執行一次,只能修飾靜態方法

  • 測試執行順序:BeforeClass -> (Before -> Test -> After -> … ) -> AfterClass

示例:利用 JUnit4 編寫 EmployeeDAOTest 的測試類。

package com.yusael._01_junit.junit4;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

// EmployeeDAO組件的測試類
public class EmployeeDAOTest {
	@BeforeClass
	public static void staticInit() throws Exception {
		System.out.println("static - Init");
	}
	@AfterClass
	public static void staticDestroy() throws Exception {
		System.out.println("static - Destroy");
	}
	@Before
	public void Init() throws Exception {
		System.out.println("初始化操作");
	}
	@After
	public void Destory() throws Exception {
		System.out.println("銷燬操作");
	}
	@Test
	public void testSave() throws Exception {
		System.out.println("保存測試");
	}
	@Test
	public void testDelete() throws Exception {
		System.out.println("刪除測試");
	}
}

在這裏插入圖片描述

使用斷言方式(瞭解)

這個不是很常用,只需要瞭解即可。

期望值: 斷言時希望是多少。
真實值: 程序內部運算之後實際是多少。

斷言成功: 期望值和真實值相同,此時顯示綠條。
斷言失敗: 期望值和真實值不同,此時顯示紅條。

斷言

  • Assert.assertEquals(message, expected, actual):比較的值
    message:斷言失敗的提示信息,斷言成功不會顯示
    expected:期望值
    actual:真實值
    若真實值和期望值想等,則斷言成功 —> 綠條
  • Assert.assertSame(message, expected, actual):比較地址,斷言是同一個對象
    Assert.assertNotSame(message, expected, actual):斷言不是同一個對象
  • Assert.assertTrue(message, condition):斷言 condition 應該爲 TRUE
    Assert.assertFalse(message, condition):斷言 condition 應該爲 FALSE
  • Assert.assertNull(message, object):斷言對象 object 爲 null
    Assert.assertNotNull(message, object):斷言對象 object 不爲 null
  • @Test(expected=ArithmeticException.class):期望該方法拋出 ArithmeticException 異常
  • @Test(timeout=400):期望該方法在400毫秒之內執行完成

示例:利用斷言進行對數學方法類進行測試。

package com.yusael._01_junit.asserted;

/**
 * 數學運算功能
 * @author yusael
 */
public interface IMath {
	/**
	 * 兩個數相加
	 * @param a 加數
	 * @param b 加數
	 * @return 兩個數之和
	 */
	int add(int a, int b);
	
	/**
	 * 兩個數之商(考慮整除)
	 * @param a 被除數
	 * @param b 除數
	 * @return 商
	 */
	int divide(int a, int b);
}
package com.yusael._01_junit.asserted.impl;

import com.yusael._01_junit.asserted.IMath;

public class MathImpl implements IMath {
	@Override
	public int add(int a, int b) {
		return a + b;
	}

	@Override
	public int divide(int a, int b) {
		return a / b;
	}

}
package com.yusael._01_junit.asserted;

import org.junit.Test;
import com.yusael._01_junit.asserted.impl.MathImpl;
import junit.framework.Assert;

// Math測試類
public class MathTest {
	// 依賴關係
	private IMath math = new MathImpl();
	@Test
	public void testAdd() {
		int ret = math.add(1, 2);
		Assert.assertEquals(3, ret);
	}
	@Test
	public void testDivide() {
		int ret = math.divide(6, 2);
		Assert.assertEquals(3, ret);
	}
	// 期望拋出ArithmeticException異常, 不拋則測試不通過
	@Test(expected=ArithmeticException.class) 
	public void testException() {
		math.divide(2, 0); // 拋出ArithmeticException異常, 測試通過
	}
}

在這裏插入圖片描述

XML 以及約束

XML(eXtensible Markup Language),是一種可擴展的標記語言,類似 HTML。

XML技術是W3C組織(World Wide Web Consortium萬維網聯盟)發佈的,目前遵循的是W3C組織於2000年發佈的XML1.0規範。
XML被廣泛認爲是繼Java之後在Internet上最激動人心的新技術。
XML的樹狀結構簡單,清晰,無論是人還是計算機都能輕鬆解析。
XML作爲一種公訂的、開放的標準,不受知識產權的限制。

HTML: 顯示頁面,網頁. 學習裏面自帶的標籤
XML: 傳輸數據,而非顯示數據
XML標籤沒有被預定義,需要用戶自行定義標籤。

爲什麼要學XML:

  • XML是一種通用的數據交換格式;
  • 許多項目都採用XML作爲數據交換格式;
  • 掌握XML是軟件開發人員的一項基本技能;
    Struts、Spring、Hibernate、Mybatis 等任意一個 Java EE 框架中都可用XML做配置文件。

XML語法

XML有兩個編碼: 內容編碼、文件本身的編碼;要保證兩個編碼相同,都爲 UTF-8。

一個XML文檔必須有且僅有一個根標籤不允許標籤嵌套區分大小寫

在編寫XML文檔時,

  • 需要先使用文檔聲明來聲明XML文檔,且必須出現在文檔的第一行。
    最簡單的語法,如:<?xml version="1.0"?>
  • encoding 屬性說明文檔所使用的字符編碼,默認爲 UTF-8。
    保存在磁盤上的文件編碼要與聲明的編碼一致。
    如:<?xml version="1.0" encoding="UTF-8"?>
  • standalone 屬性說明文檔是否獨立,即是否依賴其他文檔。
    如:<?xml version=”1.0” standalone=”yes”?>

CDATA 是 Character Data 的縮寫:

  • 作用:把標籤當做普通文本內容;
    解析器不對 CDATA 區中的內容進行解析,而是將這些數據原封不動地交給程序去處理。
  • 語法:<![CDATA[數據內容]]>

xml 一般情況下不會要求去寫,大致看得懂即可

<?xml version="1.0" encoding="UTF-8"?>
<contacts>
	<linkman id="1">
		<name>Will</name>
		<email>[email protected]</email>
		<address>成都</address>
		<group>叩丁狼教育</group>
	</linkman>
	<linkman id="2">
		<name>Stef</name>
		<email>[email protected]</email>
		<address>成都</address>
		<group>叩丁狼教育</group>
	</linkman>
</contacts>

DTD 約束(瞭解)

在這裏插入圖片描述

Scheme 約束(瞭解)

在這裏插入圖片描述

DOM

DOM(Document Object Model):文檔對象模型

  • 使用面問對象的方式,把 XML 文件中的結構使用對象來表示。

在 XML 中,一切皆節點(Wode)。

  • Node:節點
    • Document:文檔節點(XML 文件)
    • Element:元素節點(使用 <> 表示標籤)
    • Attribute:屬性節點(元素上屬性名 = “屬性值”)
    • Text:文本節點(元素之間的內容)

在這裏插入圖片描述
在這裏插入圖片描述

獲取Document文檔對象

DOM(Document Object Model):文檔對象模型

  • 使用面問對象的方式,把 XML 文件中的結構使用對象來表示。
    使用 Java 代碼操作 XML
    使用 JavaScript 操作 HTML

特點

  • 在加載的時候,一次性把整個XML文檔加載進內存,在內存中形成一顆樹對象(Document )。
  • 我們以後使用代碼操作 Document,其實操作的是內存中的 DOM 樹;和本地磁盤中的XML文件沒有直接關係。
  • 比如:我保存了一個聯繫人,僅僅是內存中多了一個聯繫人,但是在XML文件中沒有新增的痕跡。除非做 同步操作:把內存中的數據更新到XML文件。( 增刪改操作完之後,都需要做同步操作。)
  • 缺點:若XML文件過大,可能造成內存溢出

獲取 Document 文檔對象

package com.yusael._03_dom;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

// DOM操作測試類
public class DOMTest {
	private File f = new File("F:/java/JavasePro/JUnit-XML-DOM-DOM4J/contacts.xml");
	// 如何獲取Document文檔對象
	@Test
	public void testGetDocument() throws Exception {
		// 1):創建DocumentBuilderFactory對象(意識:工廠類中一般都有一個靜態方法用於返回當前工廠類對象)
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// 2):根據工廠對象, 創建DocumentBuilder對象
		DocumentBuilder builder = factory.newDocumentBuilder();
		// 3):根據builder對象去解析一個已經存在的XML文件, 從而得到Document對象.
		Document doc = builder.parse(f); // [#document: null]
	}
}

在這裏插入圖片描述
根據 DocumentBuilder 創建 Document 對象,有兩種方式:

  • 當XML文檔不存在時,使用 newDocument(),在內存中先創建出一顆 樹對象(Document)。
Document doc=builder.newDocument();
  • 當XML文檔存在時,我們只需要直接解析即可。
Document doc = builder.parse(File對象);

什麼是解析(parse):一般而言,把使用 String 描述的事物,轉換爲描述該事物的類型。

// 解析時間
Date d = DateFormat對象.parse("2018-10-10");

得到某個具體的文本節點的內容:取出第二個聯繫人的名字

操作步驟:

  1. 獲取 Document 文檔對象
  2. 獲取 XML 中的根元素 contacts
  3. 獲取第二個聯繫人元素 linkman
  4. 獲取 linkman 元素下的 name 子元素
  5. 獲取 name 元素的文本內容
// 需求1、得到某個具體的文本節點的內容:取出第二個聯繫人的名字.
@Test
public void test1() throws Exception {
	// 1):獲取Document文檔對象.
	Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
	// 2):獲取XML中的根元素(contacts).
	Element root = doc.getDocumentElement();
	// 3):獲取第二個聯繫人元素(linkman).
	Element linkmanEl = (Element)root.getElementsByTagName("linkman").item(1);
	// 4):獲取linkman元素下的name子元素.
	Element nameEl = (Element)root.getElementsByTagName("name").item(0);
	// 5):獲取name元素的文本內容.
	System.out.println(nameEl.getTextContent());
}

修改某個元素節點的主體內容:把第一個聯繫人的郵箱改掉

操作步驟:

  1. 獲取 Document 文檔對象
  2. 獲取 XML 中的根元素 contacts
  3. 獲取第一個聯繫人元素 linkman
  4. 獲取 linkman 元素下的 email 子元素
  5. 設置 email 元素的新的文本內容 will@
  6. 同步操作:把內存中的數據同步更新到磁盤的XML中
    核心類:Transformer
// 需求2、修改某個元素節點的主體內容:把第一個聯繫人的郵箱改掉.
@Test
public void test2() throws Exception {
	// 1):獲取Document文檔對象.
	Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
	// 2):獲取XML中的根元素(contacts).
	Element root = doc.getDocumentElement();
	// 3):獲取第一個聯繫人元素(linkman).
	Element linkmanEl = (Element)root.getElementsByTagName("linkman").item(0);
	// 4):獲取linkman元素下的email子元素.
	Element emailEle = (Element)linkmanEl.getElementsByTagName("email").item(0);
	// 5):設置email元素的新的文本內容(will@).
	emailEle.setTextContent("will@");
	// 6):同步操作:把內存中的數據同步更新到磁盤的XML中.核心類:Transformer.
	TransformerFactory factory = TransformerFactory.newInstance();
	Transformer trans = factory.newTransformer();
	Source xmlSource = new DOMSource(doc); // 源: 內存中的Document對象
	Result outputTarget = new StreamResult(f); // 目標: 磁盤中的XML文件(contacts.xml)
	trans.transform(xmlSource, outputTarget); // 同步操作
}

在這裏插入圖片描述

向指定元素節點中增加子元素節點:增加一個新的聯繫人信息

操作步驟:

  1. 獲取 Document 文檔對象
  2. 獲取XML中的根元素 contacts
  3. 創建一個 linkman 元素的片段
    1. 創建 linkmannameemailaddressgroup 元素
    2. nameemailaddressgroup 元素設置文本內容
    3. nameemailaddressgroup 元素作爲 linkman 元素的子元素
    4. linkman 元素作爲根元素的子元素
  4. 同步操作:把內存中的數據同步更新到磁盤的XML中
    核心類:Transformer.
// 需求3,向指定元素節點中增加子元素節點:增加一個新的聯繫人信息.
@Test
public void test3() throws Exception {
	// 1):獲取Document文檔對象.
	Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
	// 2):獲取XML中的根元素(contacts).
	Element root = doc.getDocumentElement();
	// -----------------------------------------------------
	// 3):創建一個linkman元素的片段.
	// 3.1):創建linkman,name,email,address,group元素
	Element linkmanEl = doc.createElement("linkman");
	Element nameEl = doc.createElement("name");
	Element emailEl = doc.createElement("email");
	Element addressEl = doc.createElement("address");
	Element groupEl = doc.createElement("group");
	// 3.2):給name,email,address,group元素設置文本內容
	linkmanEl.setAttribute("id", "3"); // linkman設置id屬性
	nameEl.setTextContent("yusael");
	emailEl.setTextContent("[email protected]");
	addressEl.setTextContent("蘇州");
	groupEl.setTextContent("HELLO");
	// 3.3):把name,email,address,group元素作爲linkman元素的子元素.  
	linkmanEl.appendChild(nameEl);
	linkmanEl.appendChild(emailEl);
	linkmanEl.appendChild(addressEl);
	linkmanEl.appendChild(groupEl);
	// 3.4):把linkman元素作爲根元素的子元素
	root.appendChild(linkmanEl);
	// -----------------------------------------------------
	// 4):同步操作:把內存中的數據同步更新到磁盤的XML中.核心類:Transformer.
	TransformerFactory factory = TransformerFactory.newInstance();
	Transformer trans = factory.newTransformer();
	trans.transform(new DOMSource(doc), new StreamResult(f));
}

操作XML元素屬性:設置/獲取第三個聯繫人的id屬性

操作步驟:

  1. 獲取 Document 文檔對象
  2. 獲取XML中的根元素 contacts
  3. 獲取第三個聯繫人元素 linkman
  4. 獲取 linkman 元素下的 id 屬性值 / 設置 linkman 元素的 id 屬性值.
  5. 同步操作:把內存中的數據同步更新到磁盤的XML中
    核心類:Transformer
    如果是獲取屬性,是不需要同步操作的;如果是設置屬性需要同步操作。
// 需求4、操作XML元素屬性:設置/獲取第三個聯繫人的id屬性.
@Test
public void test4() throws Exception {
	// 1):獲取Document文檔對象.
	Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
	// 2):獲取XML中的根元素(contacts).
	Element root = doc.getDocumentElement();
	// 3):獲取第三個聯繫人元素(linkman).
	Element linkmanEl = (Element)root.getElementsByTagName("linkman").item(2);
	// -----------------------------------------------------
	// 4):獲取linkman元素下的id屬性/設置linkman元素的id屬性值.
	linkmanEl.setAttribute("id", "3"); // 設置第3個人的id爲3
	String id = linkmanEl.getAttribute("id"); // 獲取第3個人的id
	// -----------------------------------------------------
	// 5):同步操作:把內存中的數據同步更新到磁盤的XML中.核心類:Transformer.
	TransformerFactory factory = TransformerFactory.newInstance();
	Transformer trans = factory.newTransformer();
	trans.transform(new DOMSource(doc), new StreamResult(f));
}

刪除指定元素節點:刪除第三個聯繫人信息.

操作步驟:

  1. 獲取 Document 文檔對象
  2. 獲取XML中的根元素 contacts
  3. 獲取第三個聯繫人元素 linkman
  4. 刪除第三個 linkan 元素.(請自己的老爸來幹掉自己)
  5. 同步操作:把內存中的數據同步更新到磁盤的XML中
    核心類:Transformer
// 需求5、刪除指定元素節點:刪除第三個聯繫人信息.
@Test
public void test5() throws Exception {
	// 1):獲取Document文檔對象.
	Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
	// 2):獲取XML中的根元素(contacts).
	Element root = doc.getDocumentElement();
	// 3):獲取第三個聯繫人元素(linkman).
	Element linkmanEl = (Element)root.getElementsByTagName("linkman").item(2);
	// -----------------------------------------------------
	// 4):刪除第三個linkan元素.(請自己的老爸來幹掉自己)
	// root.removeChild(linkmanEl);
	linkmanEl.getParentNode().removeChild(linkmanEl);
	// -----------------------------------------------------
	// 5):同步操作:把內存中的數據同步更新到磁盤的XML中.核心類:Transformer.
	TransformerFactory factory = TransformerFactory.newInstance();
	Transformer trans = factory.newTransformer();
	trans.transform(new DOMSource(doc), new StreamResult(f));
}

在內存中創建一個Document對象

// 需求6、在內存中創建一個Document對象。
@Test
public void test6() throws Exception {
	// 1):獲取Document文檔對象.
	DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
	Document doc = null;
	// 如果XML存在,則解析,否則創建新的
	if (f.exists()) {
		doc = builder.parse(f);
	} else {
		doc = builder.newDocument();
		// 創建根元素, 並把根元素作爲文檔的子元素
		doc.appendChild(doc.createElement("contacts"));
	}
	// 執行操作
	// ......
	
	// 同步操作
	// ......
}

DOM4J

dom4j 是一個 Java 的 XML API,是 jdom 的升級品,用來讀寫 XML 文件的。dom4j 是一個十分優秀的JavaXML API,具有性能優異、功能強大和極其易使用的特點,它的性能超過 sun 公司官方的 dom 技術,同時它也是一個開放源代碼的軟件,可以在 SourceForge 上找到它。在IBM developerWorks 上面還可以找到一篇文章,對主流的 Java XML API 進行的性能、功能和易用性的評測,所以可以知道dom4j無論在哪個方面都是非常出色的。如今可以看到越來越多的 Java 軟件都在使用 dom4j 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 dom4j。這已經是必須使用的 jar包, Hibernate 也用它來讀寫配置文件。

簡而言之:比官方的 DOM 更牛逼! 以後操作 XML 使用這個就可以了,上面的 DOM 瞭解一下,會了 DOM,DOM4J 用起來更方便。

下面的示例就是一些很基礎常用的 demo,體驗一下,開發中還是要去看文檔。

查詢所有聯繫人的信息

import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

public class DOM4JTest {
	private File f = new File("F:/java/JavasePro/JUnit-XML-DOM-DOM4J/contacts.xml");
	// 查詢所有的聯繫人
	@Test
	public void testGetAll() throws Exception {
		// 獲取文檔對象
		SAXReader reader = new SAXReader();
		Document doc = reader.read(f);
		// 獲取根元素
		Element root = doc.getRootElement();
		// 獲取根元素下的所有linkman元素
		List<Element> linkemanElList = root.elements("linkman");
		for (Element linkmanEl : linkemanElList) {
			// 獲取每一個linkman元素的name子元素的文本內容
			// Element nameEl = linkmanEl.element("name");
			// String name = nameEl.getText();
			String id = linkmanEl.attributeValue("id");
			String name = linkmanEl.elementText("name");
			String email = linkmanEl.elementText("email");
			String address = linkmanEl.elementText("address");
			String group = linkmanEl.elementText("group");
			System.out.println(id + "_" + name + "_" + email + "_" + address + "_" + group);
			System.out.println("------------------------------");
		}
	}
}

新增一個聯繫人的信息

@Test
public void test2() throws Exception {
	// 獲取文檔對象
	SAXReader reader = new SAXReader();
	Document doc = reader.read(f);
	// 獲取根元素
	Element root = doc.getRootElement();
	
	// 創建linkman元素, 把linkman元素作爲根元素的子元素
	Element linkmanEl = root.addElement("linkman").addAttribute("id", "4");
	// 創建name,email,address,group元素, 作爲linkman子元素, 設置文本內容
	linkmanEl.addElement("name").setText("西門吹雪");
	linkmanEl.addElement("email").setText("西門@吹雪");
	linkmanEl.addElement("address").setText("萬梅山莊");
	linkmanEl.addElement("group").setText("武俠");
	
	// 同步操作
	FileWriter out = new FileWriter(f);
	doc.write(out);
	out.close(); // 必須關閉流, 否則xml會變成空白
	
	// createCompactFormat: 壓縮格式, 輸出成一行
	// createPrettyPrint: 良好的輸出格式
	
	// OutputFormat format = OutputFormat.createPrettyPrint();
	// XMLWriter writer = new XMLWriter(new FileWriter(f), format);
	// writer.write(doc);
	// writer.close();
}

總結

  • 單元測試(JUnit)環境搭建,以及測試流程得清楚;
  • XML 語法只要求能看懂(一般不會自己寫),對約束(dtd、Schema)瞭解即可;
  • DOM 還是挺重要的,因爲 JS 操作 html 也是類似的;
    DOM4J 相當於 DOM 的升級版;
    開發中一般不會自己去寫 XML,所以大致記得能幹什麼即可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章