XML文件能夠用來做爲一種小型數據庫存在,但更多時候在項目中都是用來當成配置文件用的,也就避免不了對XML文件的增上改查操做。html
在java中,解析XML文件的方式大體分爲兩種:DOM解析,SAX解析java
先來講DOM解析方式:xml解析器一次性把整個xml文檔加載進內存,而後在內存中構建一顆Document的對象樹,經過Document對象,獲得樹上的節點對象,經過節點對象訪問(操做)到xml文檔的內容。node
用的較爲多的是Dom4j工具(非官方)解析,簡單介紹下Dom4j的使用,具體API文檔請下載數據庫
SAXReader reader = new SAXReader(); //1.建立一個xml解析器對象 Document doc = reader.read(new File("xxx.xml"));//2.讀取xml文檔,返回Document對象 獲取節點: Iterator<Node> doc.nodeIterator(); //獲取當前標籤節點下的全部子節點 獲取標籤: Element elem = doc.getRootElement(); //獲取xml文檔的根標籤(通常建立doc對象後回先調用此方法獲得根標籤) Element e = elem.element("標籤名") //指定名稱的第一個子標籤 Iterator<Element> iterator = elem.elementIterator("標籤名");// 指定名稱的全部子標籤 List<Element> list = elem.elements(); //獲取全部子標籤 獲取屬性: String sttrValue = elem.attributeValue("屬性名") //獲取指定名稱的屬性值 Attribute attr = Element.attribute("屬性名");//獲取指定名稱的屬性對象 attr.getName() //獲取屬性名稱 attr.getValue() //獲取屬性值 List<Attribute> elem.attributes(); //獲取全部屬性對象 Iterator<Attribute> elem.attributeIterator(); //獲取全部屬性對象 獲取文本: elem.getText(); //獲取當前標籤的文本 elem.elementText("標籤名") //獲取當前標籤的指定名稱的子標籤的文本內容
增長: DocumentHelper.createDocument() 增長文檔 addElement("名稱") 增長標籤 addAttribute("名稱",「值」) 增長屬性 修改: Attribute.setValue("值") 修改屬性值 Element.addAtribute("同名的屬性名","值") 修改同名的屬性值 Element.setText("內容") 修改文本內容 刪除 Element.detach(); 刪除標籤 Attribute.detach(); 刪除屬性 寫出文件 XMLWriter writer = new XMLWriter(OutputStream, OutputForamt) wirter.write(Document);
簡單代碼操做步驟:api
1 //一、讀取文件
2 Document doc = new SAXReader().read(new File("xxx.xml")); 3
4 //二、修改文件 5
6 //三、寫出文件
7 FileOutputStream out = new FileOutputStream("f:/xxx.xml");//指定文件輸出的位置 8 //指定寫出的格式
9 OutputFormat format = OutputFormat.createCompactFormat(); //緊湊的格式.去除空格換行. 10 //OutputFormat format = OutputFormat.createPrettyPrint(); //格式好的格式.有空格和換行.
11 format.setEncoding("utf-8");//2.指定生成的xml文檔的編碼
12 XMLWriter writer = new XMLWriter(out,format);//建立寫出對象
13 writer.write(doc);//寫出對象
14 writer.close();//關閉流
值得注意的是Dom4j還支持xPath,這讓咱們獲取標籤獲得極大的方便。基本就須要記住兩個方法,一句代碼,即可以獲取全部想獲取到的元素ide
導入xPath支持jar包 jaxen-1.1-beta-6.jar,上面給的文檔有。工具
List<Node> selectNodes("xpath表達式"); // 查詢多個節點對象 Node selectSingleNode("xpath表達式"); // 查詢一個節點對象
例子:假設有以下這段xml,想要獲取 二班趙六 的學生的姓名編碼
1 <?xml version="1.0" encoding="UTF-8"?>
2 <root>
3 <class id="001">
4 <student id="001">
5 <name>一班--張三</name>
6 <age>20</age>
7 </student>
8 <student id="002">
9 <name>一班--李四</name>
10 <age>20</age>
11 </student>
12 </class>
13 <class id="002">
14 <student id="001">
15 <name>二班--王五</name>
16 <age>20</age>
17 </student>
18 <student id="002">
19 <name>二班--趙六</name>
20 <age>20</age>
21 </student>
22 </class>
23 </root>
普通方式獲取標籤與xpath方式獲取標籤比較spa
1 public static void main(String[] args) throws Exception { 2 SAXReader reader = new SAXReader(); 3 Document read = reader.read("./src/NewFile.xml"); 4 Element rootElement = read.getRootElement(); 5
6 //普通方式
7 List<Element> elements = rootElement.elements(); 8 for (Element element : elements) { 9 if("002".equals(element.attributeValue("id"))){ 10 List<Element> elem = element.elements(); 11 for (Element e : elem) { 12 if("002".equals(e.attributeValue("id"))){ 13 Element nameElement = e.element("name"); 14 System.out.println("普通方式: "+nameElement.getText()); 15 } 16 } 17 } 18 } 19 //xpath方式
20 Element nameElement = (Element)rootElement.selectSingleNode("/root/class[@id='002']/student[@id='002']/name"); 21 System.out.println("xpath方式: "+nameElement.getText()); 22 }
執行結果:code
普通方式: 二班--趙六
xpath方式: 二班--趙六
可見支持xpath對操做xml文檔有多麼方便
簡單介紹xpath的語法,具體請參照:,http://www.w3cschool.cn/index-14.html,附實例文檔
/ 絕對路徑 表示從xml的根位置開始或子元素(一個層次結構) // 相對路徑 表示不分任何層次結構的選擇元素。 * 通配符 表示匹配全部元素 [] 條件 表示選擇什麼條件下的元素 @ 屬性 表示選擇屬性節點 and 關係 表示條件的與關係(等價於&&) text() 文本 表示選擇文本內容
這種解析方式原理是一邊加載,一邊處理,相似於事件的處理機制,適合xml文件較大的狀況
核心API:
SAXParser類: 用於讀取和解析xml文件對象
parse(File f, DefaultHandler dh)//解析xml文件 參數一: File,讀取的xml文件。參數二: DefaultHandler,SAX事件處理程序。
簡單代碼實現:詳細請查閱api文檔
1 public class MyDefaultHandler extends DefaultHandler { 2
3 /**
4 * 開始文檔時調用 5 */
6 @Override 7 public void startDocument() throws SAXException { 8 System.out.println("MyDefaultHandler.startDocument()"); 9 } 10
11 /**
12 * 開始標籤時調用 13 * @param qName: 表示開始標籤的標籤名 14 * @param attributes: 表示開始標籤內包含的屬性列表 15 */
16 @Override 17 public void startElement(String uri, String localName, String qName, 18 Attributes attributes) throws SAXException { 19 System.out.println("MyDefaultHandler.startElement()-->"+qName); 20 } 21
22 /**
23 * 結束標籤時調用 24 * @param qName: 結束標籤的標籤名稱 25 */
26 @Override 27 public void endElement(String uri, String localName, String qName) 28 throws SAXException { 29 System.out.println("MyDefaultHandler.endElement()-->"+qName); 30 } 31
32 /**
33 * 讀到文本內容的時調用 34 * @param ch: 表示當前讀完的全部文本內容 35 * @param start: 表示當前文本內容的開始位置 36 * @param length: 表示當前文本內容的長度 37 */
38 @Override 39 public void characters(char[] ch, int start, int length) 40 throws SAXException { 41 //獲得當前文本內容
42 String content = new String(ch,start,length); 43 System.out.println("MyDefaultHandler.characters()-->"+content); 44 } 45
46 /**
47 * 結束文檔時調用 48 */
49 @Override 50 public void endDocument() throws SAXException { 51 System.out.println("MyDefaultHandler.endDocument()"); 52 } 53
54 } 55 public class Demo1 { 56 public static void main(String[] args) throws Exception{ 57 //1.建立SAXParser對象
58 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 59 //2.調用parse方法
60 /**
61 * 參數一: xml文檔 62 * 參數二: DefaultHandler的子類 63 */
64 parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); 65 } 66 }