使用SAXParser處理XML文檔
在本文中主要就如何用SAX解析xml文檔進行說明。
要解析的xml片段如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
應用程序想從這個xml文檔中讀出各個book,并且需要提供查詢功能,即給定書的id,能夠找到作者和書名。
當然,用jdom是很簡單的方式,不過如果我們讀到的是一個stream,并且比較大,那么我們最好用SAXParser,不需要把整個xml文檔裝入內(nèi)存。
首先,我們建立一個Book類,保存book相關的信息。
public class Book { public String toString() |
接下來我們新建一個類BooksSAXHandler,它擴展了DefaultHandler,用于解析xml。SAX解析是以事件為基礎的,在這里我們處理三個事件,分別是startElement,endElement以及characters。為了獲取一個element里面的text值,我們需要程序知道當前在處理那個結(jié)點,但僅僅知道結(jié)點也是不夠的,因為可以有同名的結(jié)點,故此我們引入currentPath,這樣可以唯一的定位到要處理的結(jié)點。下面給出了解析的方法,注意currentPath的用法。
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { currentPath.append(qName + "/"); if (qName.equals(ELEMENT_BOOK)) { book = new Book(); if (attributes.getQName(0).equals(ELEMENT_ID)) { book.setID(attributes.getValue(ELEMENT_ID)); } } } public void endElement(String uri, String localName, String qName) throws SAXException { currentPath .delete(currentPath.lastIndexOf(qName), currentPath.length()); if (qName.equals(ELEMENT_BOOK)) { booksMap.put(book.getID(), book); book = null; } } public void characters(char[] ch, int start, int length) throws SAXException { if (currentPath.toString().equals(NAME_PATH)) { book.setName(new String(ch, start, length)); } else if (currentPath.toString().equals(AUTHOR_PATH)) { book.setAuthor(new String(ch, start, length)); } }
接下來,我們用javax.xml.parsers.SAXParser來解析這個xml文檔,SAXParser需要兩個參數(shù),一個是要解析的stream流,另外一個就是DefaultHandler的對象。到此為止,我們已經(jīng)清楚了解析這個xml的全部過程。在附件中有例子的完整代碼。
用戶界面是用jface的TableViewer實現(xiàn)的。這里簡單介紹一下TableViewer的用法。定義了TableViewer之后,關鍵需要設置以下三個方法。
tableViewer.setContentProvider(new BooksContentProvider()); |
其中g(shù)etBooks()是提供數(shù)據(jù)的,返回所有數(shù)據(jù)的列表,在本例返回List<Book>。
BooksLabelProvider需要實現(xiàn)ITableLabelProvider,主要是返回table的對應列的值。其中有兩個主要的方法,String getColumnText(Object element, int columnIndex) 以及Image getColumnImage(Object element, int columnIndex)。
在本例中,element對應一個Book對象,getColumnText返回table對應列的文本值,包括Book的ID,Name,Author等。getColumnImage 則返回table對應列的Image,這里對應Book的Image。
最后的運行結(jié)果是:
【編輯推薦】