Java學習總結(21)——XML文檔解析:DOM解析,SAX解析
1.可擴展性標記語言(eXtensible Markup Language)
2.XML用於描述數據
3.應用場合:
(1)持久化存儲數據
(2)數據交換
(3)數據配置
4.XML語法
(1)文檔類型:
在編寫XML文檔時,需要先使用文檔聲明,聲明XML文檔的類型。
最簡單的聲明語法:
<?Xml version=”1.0” ?>
用encoding屬性說明文檔的字符編碼:
<?Xml version=”1.0” encoding=”GB2312” ?>
(2)元素
對於XML標簽中出現的所有空格和換行,XML解析程序都會當標簽中的內容進行處理,例如:下面兩段內容的意義是不一樣的:
由於在XML中,空格和換行都作為原始內容被處理,所以,在編寫XML文件時,使用換行和縮進等方式來讓原文中的把內容清晰可讀的“良好”書寫習慣可能要被迫改變
XML文件中的註釋采用:“<!--註釋內容-->”格式
註意:
XML聲明之前不能有註釋
註釋不能嵌套
(4)格式:
必須有XML聲明語句
必須有且僅有一個根元素
標簽大小寫敏感
屬性值用雙引號或單引號
標簽成對
元素正確嵌套
例1(聯系):
使用XML描述下表中的學生成績信息,XML文件為student.xml
XML表示如下:
<?xml version="1.0" encoding="GBK"?> <students> <student> <id>1</id> <name>張同</name> <subject>java</subject> <score>89</score> </student> <student> <id>2</id> <name>李佳</name> <subject>sql</subject> <score>58</score> </student> </students>
將文件拉入瀏覽器看是否可以顯示:
顯示結果:
二.DOM(Doncument Object Model)解析
1.DOM解析是將XML文件在的內存中換成一個文檔對象模型(通常稱為DOM樹),應用程序可以在任何時候訪問XML文檔中的任何一部分數據,因此,DOM解析的機制也被稱為隨機訪問機制。
註意:DOM解析對內存的需求比較高
2.DOM解析的步驟:
(1)建立DocumentBuilderFactory
(2)建立DocumentBuilder
(3)建立Document
(4)建立NodeList
(5)進行XML信息讀取
3.DOM數模型
例2(DOM解析XML文件,我們以剛才寫好的XML文件為例):
package org.xml.dom;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class DOMParserDemo {
public static void main(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 1.建立DOM工廠
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();// 2.獲得DOM解析器
Document document = builder.parse("e:" + File.separator
+ "userinfo.xml");// 3.指定解析的文件路徑,將XML文件在解析成DOM樹
NodeList nodelist = document.getElementsByTagName("province");// 根據標簽名獲取獲取所有該標簽名的節點
String value = nodelist.item(3).getFirstChild().getTextContent();// 獲取節點中的內容
System.out.println("解析節點名稱為province的第三個元素中的內容為:" + value);
System.out.println("獲取節點名稱:" + nodelist.item(3).getNodeName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:
例3(動態創建XML文件):
package org.xml.dom;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
public class DOMCreateDemo {
public static void main(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 1.創建DOM工廠
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();// 2.獲取DOM解析器
Document doc = builder.newDocument();// 3.新建文檔
Element students = doc.createElement("students");
Element student = doc.createElement("student");
Element id = doc.createElement("id");
Element name = doc.createElement("name");
Element subject = doc.createElement("subject");
Element score = doc.createElement("score");
Text idtext = doc.createTextNode("1");
Text nametext = doc.createTextNode("王昭君");
Text subjecttext = doc.createTextNode("java");
Text scoretext = doc.createTextNode("99.4");
students.appendChild(student);
student.appendChild(id);
student.appendChild(name);
student.appendChild(subject);
student.appendChild(score);
id.appendChild(idtext);
name.appendChild(nametext);
subject.appendChild(subjecttext);
score.appendChild(scoretext);
doc.appendChild(students);
TransformerFactory factory2 = TransformerFactory.newInstance();
Transformer tf = factory2.newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");//自動換行
tf.setOutputProperty(OutputKeys.ENCODING, "GBK");
DOMSource soure = new DOMSource(doc);// 生成DOMSource裏邊包含了doc對象
StreamResult rs = new StreamResult(new File("f:" + File.separator
+ "student.xml"));//StreamResult封裝了目標輸出文件
tf.transform(soure, rs);//開始寫入
System.out.println("student.xml文件生成成功......");
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:
三.SAX(Simple APIs for XML)解析
1.SAXs是一個用於處理XML事件驅動的“推”模型,在讀取文檔時激活一系列事件,這些事件被推給事件處理器,然後由事件處理器提供對文檔內容的訪問
2.通常用於查找,讀取XML數據
3.SAX解析步驟:
(1)編寫SAX解析器,該解析器類繼承自DefaultHanderler類,同時覆寫相關方法
(2)建立SAX解析工廠:
(3)構造解析器:
(4)解析XML:
例4(利用SAX解析XML文檔):
(1)自定義SAX解析器
package org.xml.saxdemo;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
//自定義解析器
public class MySAXHandler extends DefaultHandler {
// 文檔開始解析時自動調用該方法
@Override
public void startDocument() throws SAXException {
System.out.println("XMl文檔開始解析..");
}
// 開始解析元素時,自動調用此方法
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.print("<" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
System.out.print(" " + attributes.getLocalName(i) + "=\""
+ attributes.getValue(i) + "\"");
}
System.out.print(">");
}
// 元素解析結束時自動調用該方法
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.print("</" + qName + ">");
}
// 解析文本數據時自動調用該方法
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.print(new String(ch, start, length));
}
// 文檔解析結束時自動調用該方法
@Override
public void endDocument() throws SAXException {
System.out.println("文檔解析結束..");
}
}
(2)測試解析XML文件
package org.xml.saxdemo;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXDemo {
public static void main(String[] args) {
MySAXHandler handler=new MySAXHandler();
//1.建立sax解析工廠
SAXParserFactory factory=SAXParserFactory.newInstance();
//2.構造解析器
try {
SAXParser parser=factory.newSAXParser();
//3.解析XML
parser.parse("e:"+File.separator+"userinfo.xml",handler );
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:
例5(解析XML文檔並將其封裝如JavaBean對象中):
(1)編寫JavaBean代碼:
User對象:
package org.xml.saxbean2;
import java.util.List;
public class User {
private String id;
private String name;
private List<Address> adds;
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 List<Address> getAdds() {
return adds;
}
public void setAdds(List<Address> adds) {
this.adds = adds;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", adds=" + adds + "]";
}
}
Address對象:
package org.xml.saxbean2;
public class Address {
private String type;
private String province;
private String city;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address [type=" + type + ", province=" + province + ", city="
+ city + "]";
}
}
(2)自定義解析器:
package org.xml.saxbean2;
import java.util.*;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
// SAX解析器
public class MySAXHandler extends DefaultHandler {
private User user;
private Address address;
private List<Address> addressList;
private List<User> userList;
private String text; // 存儲文本
// XML文檔開始解析時自動調用該方法
@Override
public void startDocument() throws SAXException {
System.out.println("開始讀取XML文檔..");
}
// 開始解析文檔元素時自動調用該方法
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if ("users".equals(qName)) {
userList = new ArrayList<User>();
} else if ("user".equals(qName)) {
user = new User();
} else if ("adds".equals(qName)) {
addressList = new ArrayList<Address>();
} else if ("address".equals(qName)) {
address = new Address();
address.setType(attributes.getValue(0));
}
}
// 解析文本數據時調用
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
text = new String(ch, start, length);
}
// 元素解析完畢時開始調用
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if ("id".equals(qName)) {
user.setId(text);
} else if ("name".equals(qName)) {
user.setName(text);
} else if ("province".equals(qName)) {
address.setProvince(text);
} else if ("city".equals(qName)) {
address.setCity(text);
} else if ("address".equals(qName)) {
addressList.add(address);
} else if ("adds".equals(qName)) {
user.setAdds(addressList);
} else if ("user".equals(qName)) {
userList.add(user);
}
}
// 文檔解析完畢時開始調用
@Override
public void endDocument() throws SAXException {
for (User user : userList) {
System.out.println(user);
}
}
}
(3)測試代碼
package org.xml.saxbean2;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SAXDemo {
public static void main(String[] args) {
SAXParserFactory factory=SAXParserFactory.newInstance();
try {
SAXParser parser=factory.newSAXParser();
parser.parse(new File("e:"+File.separator+"userinfo.xml"),new MySAXHandler());
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:
例5(解析網絡XML文檔,獲取當前天氣預報):
(1)編寫天氣預報JavaBean
(2)自定義SAX解析器
(3)測試SAX解析,獲取當前天氣信息
Java學習總結(21)——XML文檔解析:DOM解析,SAX解析