章節目錄
1.XML解析概述
當將數據存儲在XML後,我們就希望通過程序獲得XML的內容。如果我們使用Java基礎所學習的IO知識是可以完成的。不過,你需要非常繁瑣的操作纔可以完成,且開發中會遇到不同問題。人們爲不同問題提供不同的解析方式,並提交給對應的解析器,方便開發人員操作XML。
2.解析方式、解析器、解析開發包
2.1解析方式
開發中比較常見的解析方式有三種:
- DOM:要求解析器把整個XML文檔裝在到內存中,並解析成一個Document對象。
優點:元素與元素之間保留結構關係。故,可以進行增、刪、改、查操作
缺點:XML文檔過大,可能會導致內存溢出 - SAX:速度更快、更有效的方法。它逐行掃描文檔,一邊掃一邊解析。並以事件驅動的方式進行具體解析,每執行一行,都將觸發對應事件
優點:處理速度快,可以處理大文件
缺點:只能讀,逐行後釋放資源 - PULL:Android內置的XML解析方式,類似於SAX(瞭解)
2.2解析器
解析器:就是根據不同的解析方式提供的具體實現。有的解析器操作過於繁雜,爲了方便開發人員,有提供易於操作的解析開發包
2.3解析開發包
- JAXP:SUN公司提供支持DOM和SAX開發包
- jDom:dom4j兄弟
- jsoup:一種處理HTML特定解析開發包
- dom4j:比較常用的解析開發包,hibernate底層採用
3.DOM解析
3.1DOM解析原理
XML DOM和HTML DOM類似,XML DOM將整個XML文檔加載到內存中,生成一個DOM樹,並獲得一個Document對象。通過Document對象,就可以對DOM進行操作
3.2DOM結構模型
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5">
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.zzc.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
3.3dom4j常用API
- SaxReader對象
read():加載執行XML文檔 - Document對象
getRootElement():獲得根元素 - Element對象
elements():獲得指定名稱的所有子元素。可以不指定
element():獲得指定名稱的第一個子元素。可以不指定
getName():獲得當前元素的元素名
attributeValue():獲得指定屬性名的屬性值
elementText():獲得指定名稱子元素的文本值
getText():獲得當前元素的文本內容
3.4DOM解析開發
3.4.1 項目結構圖:
3.4.2 開發步驟:
【第一步】、創建一個java工程。如:javaweb-01-xml
【第二步】、導包
需要導入dom4j包
【第三步】、創建一個XML文件
在src目錄下創建一個web.xml文件,其內容爲:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.zzc.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
【第四步】、創建包和類
在src目錄下創建com.zzc.xml.dom4j包,並在其下創建Dom4j類
Dom4j.java:
獲取根元素信息
public class Dom4j {
public static void testDom4j() {
try {
// 1.獲取解析器
SAXReader reader = new SAXReader();
// 2.獲取document對象
Document document = reader.read("src/web.xml");
// 3.獲取根元素
Element rootElement = document.getRootElement();
// 3.1獲取根元素名稱
System.out.println(rootElement.getName());
// 3.2獲取根元素中version屬性的值
System.out.println(rootElement.attributeValue("version"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
testDom4j();
}
}
運行結果:
獲取根元素下的子元素信息
...
// 4.獲取根元素下的子元素
List<Element> childElements = rootElement.elements();
// 5.遍歷子元素
for(Element e : childElements) {
//System.out.println(e.getName());
if("servlet".equals(e.getName())) {
// 5.1獲取指定的子元素
Element servletName = e.element("servlet-name");
Element servletClass = e.element("servlet-class");
// 5.2獲取子元素的文本內容
System.out.println(servletName.getText());
System.out.println(servletClass.getText());
}
}
}
...
運行結果:
Dom4j.java:
public class Dom4j {
public static void testDom4j() {
try {
// 1.獲取解析器
SAXReader reader = new SAXReader();
// 2.獲取document對象
Document document = reader.read("src/web.xml");
// 3.獲取根元素
Element rootElement = document.getRootElement();
// 3.1獲取根元素名稱
System.out.println(rootElement.getName());
// 3.2獲取根元素中version屬性的值
System.out.println(rootElement.attributeValue("version"));
// 4.獲取根元素下的子元素
List<Element> childElements = rootElement.elements();
// 5.遍歷子元素
for(Element e : childElements) {
//System.out.println(e.getName());
if("servlet".equals(e.getName())) {
// 5.1獲取指定的子元素
Element servletName = e.element("servlet-name");
Element servletClass = e.element("servlet-class");
// 5.2獲取子元素的文本內容
System.out.println(servletName.getText());
System.out.println(servletClass.getText());
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
testDom4j();
}
}
4. SAX解析
4.1 開發步驟
【第一步】、創建一個XML文件
在com.zzc.xml.sax目錄下創建一個person.xml,其內容爲:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>至尊寶</name>
<age>2000</age>
</person>
<person>
<name>朱志成</name>
<age>22</age>
</person>
</persons>
【第二步】、創建類
在com.zzc.xml.sax目錄下創建
Person.java
public class Person {
private String name;
private int age;
setter/getter()
}
PersonHandler.java
public class PersonHandler extends DefaultHandler {
private List<Person> persons;
private Person person;
private String tag; // 記錄標籤名
/**
* 開始處理文檔
*/
@Override
public void startDocument() throws SAXException {
persons = new ArrayList<Person>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// System.out.println("開始一個元素" + qName);
if (null != qName) {
tag = qName;
}
if (null != qName && qName.equals("person")) {
person = new Person();
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
String str = new String(ch, start, length);
if (null != tag && tag.equals("name")) {
person.setName(str);
} else if (null != tag && tag.equals("age")) {
Integer age = Integer.parseInt(str);
person.setAge(age);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// System.out.println("結束一個元素" + qName);
if (qName.equals("person")) {
persons.add(person);
}
tag = null;
}
/**
* 處理文檔結束
*/
@Override
public void endDocument() throws SAXException {
}
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
SAXTest.java
public class SAXTest {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// 1.獲得解析工廠SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2.從工廠獲取解析器SAXParser
SAXParser parser = factory.newSAXParser();
// 3.加載文檔Document註冊解析器
// 3.1編寫處理器
PersonHandler handler = new PersonHandler();
parser.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("com\\zzc\\xml\\sax\\person.xml"), handler);
List<Person> persons = handler.getPersons();
for (Person p : persons) {
System.out.println(p);
}
}
}
運行結果: