JAXP(Java API for XML Parsing)
過去幾年中,XML分折已經(jīng)被標(biāo)準(zhǔn)為兩個(gè)不同的處理模型:SAX(Simple API for XML)以及DOM(Document Object Model)。這兩個(gè)標(biāo)準(zhǔn)提供了各種API以便開發(fā)人員處理XML數(shù)據(jù),分別適用於不同的分折需要。JAXP是SUN公司在1999年後期提出的,它是一個(gè)API,但更準(zhǔn)確地說,它應(yīng)該是一個(gè)抽象層。JAXP並不提供解折功能!沒有SAX、DOM或其它XML解折API,我們無法解折XML。 一、SAX(Simple API for XML) SAX是基於事件的處理模型,在此模型中,解折程序按序列順序解釋數(shù)據(jù)元素,同時(shí)基於所選擇的結(jié)構(gòu)回調(diào)函數(shù)。它最大的優(yōu)點(diǎn)是:它並不把任何XML文檔裝載進(jìn)內(nèi)存,因此被認(rèn)為是非常迅速和輕便的。它使用一個(gè)序列只讀的方法,並不支持對(duì)XML元素的隨機(jī)訪問。 基本實(shí)現(xiàn)由以下三個(gè)驟組成 1、實(shí)現(xiàn)一個(gè)擴(kuò)展DefaultHandler的類,並為每種類型的結(jié)構(gòu)包含回調(diào)方法。 2、初始化一個(gè)新的SAXParser類。Parser讀到XML源文件,並觸發(fā)DefaultHandler類中所實(shí)現(xiàn)的一個(gè)回調(diào)方法 3、須序讀取XML源文件。在須序讀取中,無法隨機(jī)訪問結(jié)構(gòu)中的元素。剩下的工作取決於Handler類中你的實(shí)現(xiàn)方案。 示例 書寫一個(gè)用於讀取的XML文檔test.xml,具體內(nèi)容如下: <?xml version="1.0" encoding="UTF-8"?> <simple date=" <name>wang</name> <location>China DongGuan</location> </simple>
實(shí)現(xiàn)一個(gè)擴(kuò)展DefaultHandler的類SaxTestHandler.java代碼如下 package mypack;
import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;
public class SaxTestHandler extends DefaultHandler {
// 重載DefaultHandler類的方法 // 以攔截SAX事件通知。 //
/* 開始解折文析進(jìn)執(zhí)行 */ public void startDocument() throws SAXException { System.out.println("SAX Event: START DOCUMENT"); }
/* 結(jié)束解折時(shí)執(zhí)行 */ public void endDocument() throws SAXException { System.out.println("SAX Event: END DOCUMENT"); }
/* 遇到一個(gè)節(jié)點(diǎn)時(shí)執(zhí)行 */ public void startElement(String namespaceURI, String localName, String qName, Attributes attr) throws SAXException { System.out.println("SAX Event: START ELEMENT[ " + localName + " ]"); // System.out.println(namespaceURI+";;;"+qName);
// 如果有屬性,打印屬性和屬性值 for (int i = 0; i < attr.getLength(); i++) { System.out.println(" ATTRIBUTE: " + attr.getLocalName(i) + " VALUE: " + attr.getValue(i)); } }
// 元素?cái)?shù)據(jù) public void characters(char[] ch, int start, int length) throws SAXException { String s = new String(ch, start, length); System.out.println(s); } }
這個(gè)類實(shí)現(xiàn)了內(nèi)容處理接口的實(shí)現(xiàn),該實(shí)現(xiàn)只做了一個(gè)簡(jiǎn)單的處理:把有關(guān)XML文檔的內(nèi)容打印到系統(tǒng)控制臺(tái)。
一個(gè)SAXParser類,用於指定解折器並讀取XML文檔然後調(diào)用Handler類的回調(diào)方法。代碼如下: package mypack;
import java.io.FileReader;
import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory;
public class SAXTest {
/** * @param args */ public static void main(String[] args) { // TODO 自動(dòng)產(chǎn)生方法 try { // 建立SAX2解折器 XMLReader xr = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
// 安裝ContentHandler內(nèi)容處理類 SaxTestHandler handler=new SaxTestHandler(); xr.setContentHandler( handler );
// 解折文檔 xr.parse(new InputSource(new FileReader("D:\\MyProject\\Ewebsite\\XML\\JavaSource\\test.xml"))); } catch (Exception e) { e.printStackTrace(); } } }
執(zhí)行SAXTest可以打印出test.xml文件的內(nèi)容(節(jié)點(diǎn)名,節(jié)點(diǎn)的屬性及值,元素內(nèi)容)
二、DOM(Document Object Model) XML將數(shù)據(jù)組織為一棵樹,所以DOM就是對(duì)這棵樹的一個(gè)對(duì)象描敘。通俗的說,就是通過解折XML文檔,為XML文檔在邏輯上建立一個(gè)樹模型,樹的節(jié)點(diǎn)就是一個(gè)個(gè)對(duì)象。我們通過存到這些對(duì)象就能夠存取XML文檔的內(nèi)容。當(dāng)XML文檔很大時(shí),這個(gè)過程可能需要一塊相當(dāng)大的內(nèi)存,這可能出現(xiàn)內(nèi)存不足的現(xiàn)象。
使用DOM處理的基本步驟如下: 1、實(shí)例一個(gè)DOMParser。 2、得到一個(gè)Document對(duì)象。 3、使用Document對(duì)象訪問代表了XML文檔中元素的節(jié)點(diǎn)。
XML源被完全讀入內(nèi)存,並用Document對(duì)象表示。這就使得應(yīng)用程序能夠隨機(jī)訪問任何節(jié)點(diǎn),這一點(diǎn)也是SAX所不能做到的。
一個(gè)讀取XML文檔的DOM處理示例 package mypack;
import java.io.FileReader; import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.xerces.parsers.DOMParser;//導(dǎo)入DOMParser解折器 import org.w import org.w import org.w import org.xml.sax.InputSource; import org.xml.sax.SAXException;
public class DOMTest {
/** * @param args * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { // TODO 自動(dòng)產(chǎn)生方法 Stub
// 實(shí)例解折器 DOMParser parser = new DOMParser(); // 以Docment對(duì)象的形式獲取DOM樹 parser.parse(new InputSource(new FileReader( "D:\\MyProject\\Ewebsite\\XML\\JavaSource\\test.xml"))); Document doc = parser.getDocument(); // 使用Document對(duì)象的方法得到NodeList對(duì)象 NodeList nl = doc.getElementsByTagName("name"); System.out.println(nl.getLength());// 標(biāo)簽的次數(shù) Node my_node = nl.item(0); // 輸出name標(biāo)簽的元素?cái)?shù)據(jù) String name = my_node.getFirstChild().getNodeValue(); System.out.println(name); } }
現(xiàn)在,既然我們已經(jīng)能夠從XML文件中提取出數(shù)據(jù)了,我們就可以把這些數(shù)據(jù)用在合適的地方,來構(gòu)筑應(yīng)用程序。
DOM對(duì)象詳解 1.基本的DOM對(duì)象
三、JAXP 1、用SAX處理XML 下面是JAXP的操作示范 (1) 創(chuàng)建已實(shí)現(xiàn)的Handler類的實(shí)例。 (2) 利用SAXParserFactory的靜態(tài)方法newInstance()方法獲取一個(gè)factory類。 (3) 通過newSAXParser()靜態(tài)方法從factory中獲取SAX分折器。 (4) 分折XML數(shù)據(jù):調(diào)用SAXParser的分折方法,把XML輸入作為第一個(gè)參數(shù),而Handler實(shí)現(xiàn)方案作為第二個(gè)參數(shù)。
示例代碼如下: package mypack;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;
public class JaxpSaxTest { /** * @param args * @throws SAXException * @throws ParserConfigurationException * @throws IOException */ public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { // TODO 自動(dòng)產(chǎn)生方法 Stub //實(shí)例一個(gè)內(nèi)容處理類 DefaultHandler handler=new SaxTestHandler(); //得到廠類 SAXParserFactory factory=SAXParserFactory.newInstance(); //在廠類中獲取SAX分折器 SAXParser parser=factory.newSAXParser(); //分折XML數(shù)據(jù) parser.parse("D:\\MyProject\\Ewebsite\\XML\\JavaSource\\test.xml",handler); } }
2、用DOM處理
步聚如下: (1)初始化一個(gè)新的Builder類。Builder類負(fù)責(zé)讀取XML數(shù)據(jù)並把XML數(shù)據(jù)轉(zhuǎn)化為樹狀表示。 (2)一旦數(shù)據(jù)轉(zhuǎn)化完成,即創(chuàng)建Document對(duì)象。一旦對(duì)象創(chuàng)建後,以後所有的對(duì)XML文檔的操作都與解折器無關(guān)了。 (3) 使用Document對(duì)象訪問代表了XML文檔中元素的節(jié)點(diǎn)。
示例代碼如下: package mypack;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;
import org.w import org.w import org.w import org.xml.sax.SAXException;
public class JaxpDomTest { /** * @param args * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { // TODO 自動(dòng)產(chǎn)生方法 Stub
// 實(shí)例一個(gè)Builder類,用DocumentBuilder的目的是為了創(chuàng)建與具體解折器無關(guān)的程序 // 廠類的靜態(tài)方法newInstance()被調(diào)用時(shí),它根據(jù)一個(gè)系統(tǒng)變量來決定具體使用哪一個(gè)解折器。 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder();
// 創(chuàng)建Document對(duì)象 Document document = builder .parse("D:\\MyProject\\Ewebsite\\XML\\JavaSource\\test.xml");
// 使用Document對(duì)象的方法得到NodeList對(duì)象 NodeList nl = document.getElementsByTagName("name"); System.out.println(nl.getLength());// 標(biāo)簽的次數(shù) Node my_node = nl.item(0); // 輸出name標(biāo)簽的元素?cái)?shù)據(jù) String name = my_node.getFirstChild().getNodeValue(); System.out.println(name); }
}
|
|