SAX解析原理:
使用Handler去逐个分析遇到的每一个节点
SAX方式解析步奏:
创建xml解析需要的handler(parser.parse(file,handler))
package com.imooc_xml.sax.handler;import java.util.ArrayList;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;import com.imooc_xml.sax.entity.Book;public class SAXParserHandler extends DefaultHandler {//使用全局变量可以使本类的各个方法通用,联系int bookIndex = 0 ;String value = null;Book book = null;private ArrayList<Book> bookList = new ArrayList<Book>();public ArrayList<Book> getBookList() {return bookList;}/*** 用来遍历xml文件的开始标签*/@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// TODO Auto-generated method stubsuper.startElement(uri, localName, qName, attributes);解析xml文件的节点属性,只有book节点有属性if(qName.equals("book")){book = new Book();bookIndex++;//已知book的属性名// attributes.getValue("id");//不知book元素的属性名和个数int num = attributes.getLength();for(int i=0;i<num;i++){//book元素的第i+1个属性名attributes.getQName(i);attributes.getValue(i);if(attributes.getQName(i).equals("id")){book.setId(attributes.getValue(i));}}}else if (!qName.equals("book")&&!qName.equals("bookstore")){//节点名 System.out.println(qName);}}/*** 用来遍历xml文件的结束标签*/@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// TODO Auto-generated method stubsuper.endElement(uri, localName, qName);//判断是否针对一本书已经遍历结束if (qName.equals("book")){bookList.add(book);book = null;System.out.println("结束遍历第"+bookIndex+"本书");}else if(qName.equals("name")){book.setName(value);}else if(qName.equals("author")){book.setAuthor(value);}else if(qName.equals("year")){book.setYear(value);}else if(qName.equals("price")){book.setPrice(value);}else if(qName.equals("language")){book.setLanguage(value);}}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {// TODO Auto-generated method stubsuper.characters(ch, start, length);//ch是节点之间的文本内容value = new String(ch, start, length);//判断空格和换行if(!value.trim().equals("")){System.out.println(value);}}/*** 用来标志解析开始*/@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stubsuper.startDocument();System.out.println("SAX解析开始");}/*** 用来标志解析结束*/@Overridepublic void endDocument() throws SAXException {// TODO Auto-generated method stubsuper.endDocument();System.out.println("SAX解析结束");}}
创建hanlder类
SAX解析准备工作:
package com.imooc_xml.sax.test;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 com.imooc_xml.sax.handler.SAXParserHandler;public class SAXTest {public static void main(String[] args) {//通过SAXParserFactory的静态newInstance()方法获取SAXParserFactory的实例factorySAXParserFactory factory = SAXParserFactory.newInstance();try {//通过factory获取SAXParser实例SAXParser parser = factory.newSAXParser();//创建一个handler对象SAXParserHandler handler = new SAXParserHandler();parser.parse("xml/books.xml", handler);} catch (ParserConfigurationException | SAXException e) {e.printStackTrace();}catch (IOException e) {e.printStackTrace();}}}
使用SAX解析xml文件的节点属性:
//只有book节点有属性if(qName.equals("book")){//已知book的属性名// attributes.getValue("id");//不知book元素的属性名和个数‘int num = attributes.getLength();for(int i=0;i<num;i++){//book元素的第i+1个属性名attributes.getQName(i);attributes.getValue(i);}}
使用SAX解析xml文件的节点值
@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {// TODO Auto-generated method stubsuper.characters(ch, start, length);//ch是节点之间的文本内容value = new String(ch, start, length);//判断空格和换行if(!value.trim().equals("")){System.out.println(value);}}
在Java中保留xml数据的结构
public class Book {private String id;private String name;private String author;private String year;private String price;private String language;
获取对象集合:
handler.getBookList().size();for(Book book:handler.getBookList()){System.out.println(book.getId());
....}