1. xml簡介
XML:指可擴展標記語言, Extensible Markup Language;類似HTML。XML的設計宗旨是傳輸數據,而非顯示數據。
一個xml文檔實例:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <company name="Tencent" address="深圳市南山區"> 3 <department deptNo="001" name="development"> 4 <employee id="devHead" position="minister">許剛</employee> 5 <employee position="developer">工程師A</employee> 6 </department> 7 <department deptNo="002" name="education"> 8 <employee position="minister" telephone="1234567">申林</employee> 9 <employee position="trainee">實習生A</employee> 10 </department> 11 </company>
第一行是 XML 聲明。它定義 XML 的版本 (1.0) 和所使用的編碼.
下一行描述文檔的根元素:<company>開始,該根元素具有2個屬性“name”,"address"。
最后一行定義根元素的結尾。</company>。
· XML 文檔形成一種樹結構
· XML 文檔必須包含根元素。該元素是所有其他元素的父元素。
· XML 文檔中的元素形成了一棵文檔樹。這棵樹從根部開始,並擴展到樹的最底端。
所有元素均可擁有子元素:
1 <root> 2 3 <child> 4 5 <subchild>.....</subchild> 6 7 </child> 8 9 </root>
父、子以及同胞等術語用於描述元素之間的關系。父元素擁有子元素。相同層級上的子元素成為同胞(兄弟或姐妹)。
1.1 節點
節點:XML文檔中的所有節點組成了一個文檔樹(或節點樹)。XML文檔中的每個元素、屬性、文本等都代表着樹中的一個節點。樹起始於文檔節點,並由此繼續伸出枝條,直到處於這棵樹最低級別的所有文本節點為止,常用節點類型如下表所示:
| 節點類型 |
附加說明 |
實例 |
| 元素節點(Element) |
XML標記元素 |
<company>…</company> |
| 屬性節點(Attribute) |
XML標記元素的屬性 |
name=”Tencent” |
| 文本節點(Text) |
包括在XML標記中的文本段 |
工程師A |
| 文檔類型節點(DocumentType) |
文檔類型聲明 |
﹤!DOCTYPE…﹥ |
| 注釋節點Comment |
XmlComment類注釋節點。 |
<!—文檔注釋-> |
(1) 節點關系
通過上面的XML文檔,我們構建出如下樹狀文檔對象模型:

1 <?xml version="1.0" encoding="UTF-8"?> 2 <bookstore> 3 <book category="COOKING"> 4 <title lang="en">Everyday Italian</title> 5 <author>Giada De Laurentiis</author> 6 <year>2005</year> 7 <price>30.00</price> 8 </book> 9 <book category="CHILDREN"> 10 <title lang="en">Harry Potter</title> 11 <author>J K. Rowling</author> 12 <year>2005</year> 13 <price>29.99</price> 14 </book> 15 <book category="WEB"> 16 <title lang="en">Learning XML</title> 17 <author>Erik T. Ray</author> 18 <year>2003</year> 19 <price>39.95</price> 20 </book> 21 </bookstore>
再如上例xml文檔:

例子中的根元素是 <bookstore>。文檔中的所有 <book> 元素都被包含在 <bookstore> 中。<book> 元素有 4 個子元素:<title>、< author>、<year>、<price>。
(2)xml的特點
a). XML 的屬性值須加引號。
· 與 HTML 類似,XML 也可擁有屬性(名稱/值的對)。
· 在 XML 中,XML 的屬性值須加引號。
b). XML 文檔必須有根元素.XML 文檔必須有一個元素是所有其他元素的父元素。該元素稱為根元素。
c). XML 標簽對大小寫敏感.
· XML 元素使用 XML 標簽進行定義。
· XML 標簽對大小寫敏感。在 XML 中,標簽 <Letter> 與標簽 <letter> 是不同的。必須使用相同的大小寫來編寫打開標簽和關閉標簽。
d). XML 中的注釋語法:
<!-- This is a comment -->
e). XML 元素 vs. 屬性
1 <person sex="female"> 2 <firstname>Anna</firstname> 3 <lastname>Smith</lastname> 4 </person> 5 6 <person> 7 <sex>female</sex> 8 <firstname>Anna</firstname> 9 <lastname>Smith</lastname> 10 </person>
在第一行中,sex 是一個屬性。在第7行中,sex 則是一個子元素。兩個例子均可提供相同的信息。
2. xml 解析
xml解析方法有四種:
· DOM(JAXP Crimson 解析器):W3C為HTML和XML分析器制定的標准接口規范,基於樹,可隨機動態訪問和更新文檔的內容、結構、樣式。
· SAX(simple API for XML):不是W3C的標准,而是由XML-DEV郵件列表成員於1998年為Java語言開發的一種基於事件的簡單API。基於事件,逐行解析,順序訪問XML文檔,速度快,處理功能簡單。
· JDOM:鑒於DOM的低效率,而SAX又不能隨機處理XML文檔,Jason Hunter與Brett McLaughlin於2000年春天,開始創建一種能充分體現兩者優勢的API——JDOM(Java-based DOM,基於Java的DOM),它是一個基於Java的對象模型,樹狀結構,能使讀取、操作和寫入XML文檔,比DOM更高效,比SAX更強大,但由於使用了大量的類而不使用接口導致靈活性降低。
· DOM4J:DOM4J是一個易用的,開源的庫,用於XML,XPath,XSLT。它應用於Java平台,采用了Java集合框架並完全支持DOM,SAX,JAXP。它提供了大量的接口,因此比JDOM更具有靈活性。
2.1 DOM解析xml
DOM(Document Object Model文檔對象模型),是W3C為HTML和XML分析器制定的標准接口規范。
特點:獨立於語言,跨平台(可以在各種編程和腳本語言中使用),需要將整個文檔讀入內存,在內存中創建文檔樹,可隨即訪問文檔中的特定節點,對內存的要求比較高,經過測試,訪問速度相對於其他解析方式較慢,適用於簡單文檔的隨即處理。
常用的節點屬性:
| 屬性 |
描述 |
| nodeName |
結點名稱 |
| nodeValue |
結點內部值,通常只應用於文本結點 |
| nodeType |
節點類型對應的數字 |
| parentNode |
如果存在,指向當前結點的父親結點 |
| childNodes |
子結點列表 |
| firstChild |
如果存在,指向當前元素的第一個子結點 |
| lastChild |
如果存在,指向當前元素的最后一個子結點 |
| previousSibling |
指向當前結點的前一個兄弟結點 |
| nextSibling |
指向當前結點的后一個兄弟結點 |
| attributes |
元素的屬性列表 |
常用的節點方法:
| 操作類型 |
方法原型 |
描述 |
| 訪問節點 |
getElementById(id) |
根據ID屬性查找元素節點 |
| getElementsByName(name) |
根據name屬性查找元素集 |
|
| getElementsByTagName(tagName) |
根據元素標記名稱查找元素集 |
|
| 創建節點 |
createElement(tagName) |
創建元素節點 |
| createTestNode(string) |
創建文本節點 |
|
| createAttribute(name) |
創建屬性節點 |
|
| 插入和添加節點 |
appendChild(newChild) |
添加子節點到目標節點上 |
| insertBefore(newChild,targetChild) |
將newChild節點插入到targetChild節點之前 |
|
| 復制節點 |
CloneNode(bool) |
復制該節點,由bool確定是否復制子節點 |
| 刪除和替換節點 |
removeChild(childName) |
刪除由childName指定的節點 |
| replaceChild(newChild,oldChild) |
用newChild替換oldChild |
|
| 屬性節點操作 |
getAttribute(name) |
返回目標對象指定屬性名稱為name的屬性值 |
| setAttribute(name,value) |
修改目標節點指定屬性名稱為name的屬性值為value |
|
| removeAttribute(name) |
刪除目標節點指定屬性名稱為name的屬性 |
(1)讀取本地xml文檔解析為對象的步驟:
* 首先利用DocumentBuilderFactory創建一個DocumentBuilderFactory實例;然后利用DocumentBuilderFactory創建DocumentBuilder
//創建DocumentBuilderFactory工廠實例。 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); //通過文檔創建工廠創建文檔創建器
DocumentBuilder dBuilder = dbfactory.newDocumentBuilder();
* 然后加載XML文檔(Document) : 通過文檔創建器DocumentBuilder的parse方法解析參數URL指定的XML文檔,並返回一個Document 對象。
Document doc = dBuilder.parse(url);
* 然后獲取文檔的根結點(Element),
* 然后獲取根結點中所有子節點的列表(NodeList),
* 然后使用再獲取子節點列表中的需要讀取的結點。
實例:
books.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <bookstore> 3 <book category="COOKING"> 4 <title lang="en">Everyday Italian</title> 5 <author>Giada De Laurentiis</author> 6 <year>2005</year> 7 <price>30.0</price> 8 </book> 9 <book category="CHILDREN"> 10 <title lang="en">Harry Potter</title> 11 <author>J K. Rowling</author> 12 <year>2005</year> 13 <price>29.99</price> 14 </book> 15 <book category="WEB"> 16 <title lang="en">Learing XML</title> 17 <author>Erik T. Ray</author> 18 <year>2010</year> 19 <price>48.99</price> 20 </book> 21 </bookstore>
Books抽象類:
1 package demo; 2 3 /** 4 * 根據xml “books”文檔,新創建Books類 5 * Created by luts on 2015/12/18. 6 */ 7 public class Books { 8 private String category; 9 private String title; 10 private String language; 11 private String author; 12 private String year; 13 private String price; 14 15 public String getCategory() { 16 return category; 17 } 18 19 public void setCategory(String category) { 20 this.category = category; 21 } 22 23 public String getTitle() { 24 return title; 25 } 26 27 public void setTitle(String title) { 28 this.title = title; 29 } 30 31 public String getLanguage() { 32 return language; 33 } 34 35 public void setLanguage(String language) { 36 this.language = language; 37 } 38 39 public String getAuthor() { 40 return author; 41 } 42 43 public void setAuthor(String author) { 44 this.author = author; 45 } 46 47 public String getYear() { 48 return year; 49 } 50 51 public void setYear(String year) { 52 this.year = year; 53 } 54 55 public String getPrice() { 56 return price; 57 } 58 59 public void setPrice(String price) { 60 this.price = price; 61 } 62 }
DOM解析:
1 package demo; 2 3 import org.w3c.dom.*; 4 import org.xml.sax.SAXException; 5 6 import javax.xml.parsers.DocumentBuilder; 7 import javax.xml.parsers.DocumentBuilderFactory; 8 import javax.xml.parsers.ParserConfigurationException; 9 import java.awt.print.Book; 10 import java.io.FileNotFoundException; 11 import java.io.IOException; 12 import java.util.ArrayList; 13 import java.util.List; 14 15 /** 16 * Created by luts on 2015/12/18. 17 */ 18 public class DOMTest { 19 public static void main(String[] args){ 20 21 List<Books> books = new ArrayList<Books>(); 22 23 Books book = null; 24 25 try { 26 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 27 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 28 Document document = dBuilder.parse("src/books.xml"); 29 //找到根節點 30 Element root = document.getDocumentElement(); 31 32 System.out.println("------開始解析-------"); 33 NodeList booksList = root.getElementsByTagName("book"); 34 System.out.println("一共有" + booksList.getLength() + "本書"); 35 //遍歷book節點的所有節點 36 for (int i = 0; i < booksList.getLength(); i++){ 37 book = new Books(); 38 39 System.out.println("-----現在開始遍歷第" +(i + 1) + "本書的內容-----"); 40 //通過item(i)方法獲取一個book節點 41 Node nodeBook = booksList.item(i); 42 //獲取book節點的所有屬性集合 43 NamedNodeMap attrs = nodeBook.getAttributes(); 44 System.out.println("第" + (i + 1) + "本書有"+ attrs.getLength() + "個屬性"); 45 46 //遍歷book屬性 47 for (int j = 0; j < attrs.getLength(); j++){ 48 //通過item(index)方法獲取book節點的某一個屬性 49 Node attr = attrs.item(j); 50 //獲取屬性名和屬性值 51 System.out.println("屬性名:" + attr.getNodeName() + ", 屬性值:" + attr.getNodeValue()); 52 book.setCategory(attr.getNodeValue()); 53 54 } 55 56 57 /* 58 //如果book節點有且只有一個category屬性,可以通過將book節點進行強制類型轉換,轉換成Element類型。 59 Element bookElement = (Element) booksList.item(i); 60 //通過getAttribute("category") 61 String attrVaule = bookElement.getAttribute("category"); 62 System.out.println("category的屬性值為" + attrVaule); 63 */ 64 65 //解析book節點的子節點 66 NodeList bookchildNode = nodeBook.getChildNodes(); 67 //遍歷bookchildNode獲取每個節點的節點名和節點值 68 System.out.println("第" + (i +1) + "本書共有" + bookchildNode.getLength() + "個子節點"); 69 70 for (int k = 0; k < bookchildNode.getLength(); k++){ 71 72 //區分text類型的node和element類型的node 73 if (bookchildNode.item(k).getNodeType() == Node.ELEMENT_NODE){ 74 //獲取element類型的節點 75 System.out.println("\t第" + (k+1)+ "個節點的節點名:" + bookchildNode.item(k).getNodeName()); 76 //獲取element類型的節點值 77 System.out.println("\t節點值:" + bookchildNode.item(k).getFirstChild().getNodeValue()); 78 // System.out.println("--節點值是:" + bookchildNode.item(k).getTextContent()); 79 80 if(bookchildNode.item(k).getNodeName().equals("title")){ 81 book.setTitle(bookchildNode.item(k).getFirstChild().getNodeValue()); 82 Element nodeLang = (Element) (bookchildNode.item(k)); 83 String lang = nodeLang.getAttribute("lang"); 84 book.setLanguage(lang); 85 86 } 87 88 if(bookchildNode.item(k).getNodeName().equals("author")){ 89 book.setAuthor(bookchildNode.item(k).getFirstChild().getNodeValue()); 90 } 91 92 if(bookchildNode.item(k).getNodeName().equals("year")){ 93 book.setYear(bookchildNode.item(k).getFirstChild().getNodeValue()); 94 } 95 96 if(bookchildNode.item(k).getNodeName().equals("price")){ 97 book.setPrice(bookchildNode.item(k).getFirstChild().getNodeValue()); 98 } 99 100 } 101 } 102 103 books.add(book); 104 System.out.println("-----結束遍歷第" + (i+1)+"本書的內容------"); 105 106 } 107 System.out.println("------解析完畢!------"); 108 } 109 catch (FileNotFoundException e){ 110 System.out.println(e.getMessage()); 111 }catch (ParserConfigurationException e){ 112 System.out.println(e.getMessage()); 113 }catch (SAXException e){ 114 System.out.println(e.getMessage()); 115 }catch (IOException e){ 116 System.out.println(e.getMessage()); 117 } 118 119 //輸出bookList中的book 120 for(int m = 0; m < books.size(); m++){ 121 System.out.println("總共有" + books.size() + "本書"); 122 Books bookElemntTemp = (Books)books.get(m); 123 System.out.println("第"+(m + 1) + "本書的分類:" + bookElemntTemp.getCategory() + ", 作者:" + bookElemntTemp.getAuthor() + "語言: " +bookElemntTemp.getLanguage()); 124 125 } 126 } 127 128 129 130 }
結果:

