一.XML格式
创建一个book的xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 这是xml中的注释-->
<books>
<book> <!--一个对象.也叫做一个节点-->
<id>1</id>
<name>HeadFirstJava</name>
</book>
<book> <!--一个对象.也叫做一个节点-->
<id>2</id>
<name>Think In Java</name>
</book>
<book> <!--一个对象.也叫做一个节点-->
<id>3</id>
<name>心灵鸡汤</name>
</book>
<book> <!--一个对象.也叫做一个节点-->
<id>4</id>
<name>新华字典</name>
</book>
</books>
两种解析:
DOM:是基于document对象,在解析是把整个文件加载到内存中.只要电源不断,文档始终在内存中,进行遍历查找比较方便,但是整个文档的加载需要消耗大量的时间和内存
SAX:因为Document的耗时,我们改进产生了SAX,使用基于事件-驱动的模型,只需要加载部分内容.由于没有加载整个文档,在遍历山比较慢
二.XML应用实例(SAX解析)
创建一个book类
package com.example.model;
/**
* Created by Jun on 2016/8/18 0018.
*/
public class Book {
private int id;
private String name;
public Book() {
}
public Book(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
读取文件,解析
package com.example.utils;
import com.example.model.Book;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 对xml进行解析的类
* Created by Jun on 2016/8/18 0018.
*/
public class ParserXMLTools {
private MyHandler mHandler = new MyHandler();
private static final ParserXMLTools instance = new ParserXMLTools();
private ParserXMLTools(){
}
public static ParserXMLTools getInstance(){
return instance;
}
public List<Book> parserXMLBySax(File file) throws ParserConfigurationException, SAXException, IOException {
//--1.创建解析工厂类对象
SAXParserFactory factory = SAXParserFactory.newInstance();
//--2.通过工厂获取解析器对象
SAXParser parser = factory.newSAXParser();
//--3.解析器调用方法解析file
parser.parse(file,mHandler);
return mHandler.getBookList();
}
}
class MyHandler extends DefaultHandler{
private List<Book> mList;
private Book mBook;
private StringBuilder mStringBuilder;
public List<Book> getBookList() {
return mList;
}
/**
* 初始化集合和存储节点值的StringBuilder对象
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
super.startDocument();
mList = new ArrayList<>();
mStringBuilder = new StringBuilder();
}
/**
* <book xmlns:baidu="www.baidu.com"> xmlns 是命名空间相当于 java中的packager
*
* <baidu:tieba baidu:gem="tieba.baidu.com/gem">宝石</baidu:tieba>
*
*
* </book>
*
*
* @param uri uri指向命名空间的字符串.当命名空间没有指明时该值为空字符串
* @param localName 本地名称 当没有前缀(:之前的内容)时该值为空字符串
* @param qName 限制的 可以理解为包含前缀的localName 当属性不存在时,返回空字符串
* @param attributes 属性集
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (qName.equals("book"))
mBook = new Book();
mStringBuilder.setLength(0);//--把长度设置为0,以便开始记录新的内容.这里除了使用StringBuilder还可以使用
// Stack<String> stack = new Stack<>(); //-- 这里添加,end的时候移除
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
switch (qName){
case "id":
mBook.setId(Integer.parseInt(mStringBuilder.toString()));
break;
case "name":
mBook.setName(mStringBuilder.toString());
break;
case "book":
mList.add(mBook);
break;
default:
break;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
mStringBuilder.append(ch,start,length);
}
}
三.XML应用(DOM解析)
运行入口:
public class Test {
public static void main(String[] args) {
List<Book> bookList = new ArrayList<>();
//--1.提供一个File指向xml文件
File file = new File("XMLDemo/xml/book.xml");
//--2.调用工具类中的解析方法.进行解析
try {
// bookList = ParserXMLTools.getInstance().parserXMLBySax(file);
bookList = ParserXMLTools.getInstance().parserXMLByDom(file);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (Book book : bookList) {
System.out.println(book);
}
}
}
DOM解析方法:
public List<Book> parserXMLByDom(File file) throws ParserConfigurationException, IOException, SAXException {
List<Book> tList = new ArrayList<>();
//--1.获取DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//--2.获取DocumentBuilder对象.在构建解析器对象时会产生配置异常
DocumentBuilder builder = factory.newDocumentBuilder();
//--3.使用parser方法解析文件.获取Document对象
Document document = builder.parse(file);//org.w3c.document包
//--4.获取Document中的元素
Element element = document.getDocumentElement();
//--5.通过元素获取节点的集合
NodeList items = element.getElementsByTagName("book");
//--6.遍历节点
for (int i = 0 ;i < items.getLength() ;i ++ ){
Book book = new Book();
//--7.取出所有的子节点
Node item = items.item(i);
NodeList childNode = item.getChildNodes();
for (int j = 0 ; j < childNode.getLength() ; j ++){
//--取出节点
Node node = childNode.item(j);
//--取出节点的名称
String nodeName = node.getNodeName();
//--匹配nodeName
switch (nodeName){
default://--永远要加
break;
case "id":
book.setId(Integer.parseInt(node.getFirstChild().getNodeValue()));
break;
case "name":
book.setName(node.getFirstChild().getNodeValue());
break;
}
}//--内层循环是生成一个Book对象.外层循环是有多少个Book对象
tList.add(book);
}
return tList;
}