Java Sax解析是按照xml文件的順序一步一步的來解析,在解析xml文件之前,我們要先了解xml文件的節點的種類,一種是ElementNode,一種是TextNode
- <?xml version="1.0" encoding="UTF-8"?>
- <books>
- <book id="12">
- <name>thinking in java</name>
- <price>85.5</price>
- </book>
- <book id="15">
- <name>Spring in Action</name>
- <price>39.0</price>
- </book>
- </books>
其中,像<books>、<book>這種節點就屬於ElementNode,而thinking in java、85.5這種就屬於TextNode。
下面結合一張圖來詳細講解Sax解析。
xml文件被Sax解析器載入,由於Sax解析是按照xml文件的順序來解析,當讀入<?xml.....>時,會調用startDocument()方法,當讀入<books>的時候,由於它是個ElementNode,所以會調用startElement(String uri, String localName, String qName, Attributes attributes) 方法,其中第二個參數就是節點的名稱,注意:由於有些環境不一樣,有時候第二個參數有可能爲空,所以可以使用第三個參數,因此在解析前,先調用一下看哪個參數能用,第4個參數是這個節點的屬性。這裏我們不需要這個節點,所以從<book>這個節點開始,也就是圖中1的位置,當讀入時,調用startElement(....)方法,由於只有一個屬性id,可以通過attributes.getValue(0)來得到,然後在圖中標明2的地方會調用characters(char[] ch, int start, int length)方法,不要以爲那裏是空白,Sax解析器可不那麼認爲,Sax解析器會把它認爲是一個TextNode。但是這個空白不是我們想要的數據,我們是想要<name>節點下的文本信息。這就要定義一個記錄當上一節點的名稱的TAG,在characters(.....)方法中,判斷當前節點是不是name,是再取值,才能取到thinking in java
示例1.
- package hxw.xml;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.List;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- public class SAXParserService extends DefaultHandler
- {
- private List<Book> books;
- private Book book;
- private String preTag;
- public static void main(String[] args) throws Exception
- {
- List<Book> books = new SAXParserService().getBooks();
- for(Book book : books) {
- System.out.println("book name: " + book.getName() + ", book id: " +
- book.getId() + ", book price:" + book.getPrice());
- }
- }
- public List<Book> getBooks() throws Exception {
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("test.xml");
- parser(this, is);
- return this.books;
- }
- public void parser(SAXParserService handler, InputStream is) throws Exception {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser parser = factory.newSAXParser();
- parser.parse(is, handler);
- }
- @Override
- public void startDocument() throws SAXException
- {
- books = new ArrayList<Book>();
- }
- @Override
- public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException
- {
- if("book".equals(name)) {
- book = new Book();
- book.setId(Integer.parseInt(attributes.getValue(0)));
- }
- preTag = name;
- }
- @Override
- public void endElement(String uri, String localName, String name) throws SAXException
- {
- if("book".equals(name)) {
- books.add(book);
- book = null;
- }
- //此處必須將preTag置爲null 不然會發生將空字符串填充給name或者price
- //屬性的錯誤
- preTag = null;
- }
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException
- {
- if(null != preTag) {
- String content = new String(ch, start, length);
- if("name".equals(preTag)) {
- book.setName(content);
- } else if("price".equals(preTag)) {
- book.setPrice(Double.parseDouble(content));
- }
- }
- }
- }
示例2.
- package hxw.xml;
- import java.io.InputStream;
- import java.util.Vector;
- import javax.xml.parsers.SAXParser;
- import javax.xml.parsers.SAXParserFactory;
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
- import org.xml.sax.helpers.DefaultHandler;
- public class SAXParserService2 extends DefaultHandler
- {
- Vector<String> tagName;
- Vector<String> tagValue;
- public static void main(String[] args) throws Exception
- {
- new SAXParserService2().parser();
- }
- public void parser() throws Exception {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser parser = factory.newSAXParser();
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("people.xml");
- parser.parse(is, this);
- }
- @Override
- public void startDocument() throws SAXException
- {
- tagName = new Vector<String>();
- tagValue = new Vector<String>();
- }
- @Override
- public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException
- {
- tagName.add(name);
- for(int i = 0; i < attributes.getLength(); i++) {
- System.out.print("Attribute name is " + attributes.getQName(i) +
- "\nAttribute value is " + attributes.getValue(attributes.getQName(i)) + "\n");
- }
- }
- @Override
- public void endElement(String uri, String localName, String name) throws SAXException
- {
- }
- @Override
- public void endDocument() throws SAXException
- {
- for(int i = 0; i < tagName.size(); i++) {
- if(null != tagName.get(i) && !tagName.equals("")) {
- System.out.println("Tag Name: " + tagName.get(i));
- System.out.println("Tag Value: " + tagValue.get(i));
- }
- }
- }
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException
- {
- //正標籤添加內容 遇到反標籤就不添加
- if(tagName.size() - 1 == tagValue.size()) {
- tagValue.add(new String(ch, start, length));
- }
- }
- }