SAX
SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
解析器:解析器可以使用JAXP(javax.xml.parsers)的API创建
事件处理器:SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver 和 ErrorHandler
特点:
1. 边读边解析,应用于大型XML文档
2. 只支持读
3. 访问效率低
4. 逐行扫描文件,顺序访问
示例
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<name>编程之美</name>
<price>34.0</price>
<author>《编程之美》小组</author>
</book>
<book id="2">
<name>平凡的世界</name>
<price>56.0</price>
<author>路遥</author>
</book>
</books>
package com.gz.xml;
/**
* <br/>功能: 和xml对应的实体类
* <br/>版本: 1.0
*/
public class Book {
private String id;
private String name;
private String price;
private String author;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
package com.gz.xml;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
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 SAXXml {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
SAXParserFactory saxpf = SAXParserFactory.newInstance();
// 通过SAXParserFactory的实例获取SAXParser的实例
SAXParser parser = saxpf.newSAXParser();
MyHandler1 handler = new MyHandler1();
parser.parse("src\\main\\resources\\books.xml", handler);
for (Book book : handler.getBooks()) {
System.out.println("书本id :" + book.getId());
System.out.println("书本名字 :" + book.getName());
System.out.println("书本价格 :" + book.getPrice());
System.out.println("书本作者 :" + book.getAuthor());
System.out.println("---------------------------------");
}
}
}
/**
* <br/>功能: 事件处理器
* <br/>版本: 1.0
*/
class MyHandler extends DefaultHandler {
private List<Book> books;
private Book book;
private String tag;
@Override
public void startDocument() throws SAXException {
super.startDocument();
books = new ArrayList<Book>();
}
/**
* @Description: TODO
* @param uri 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串
* @param localName 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串
* @param qName 限定名(带有前缀),如果限定名不可用,则为空字符串
* @param attributes 连接到元素上的属性。如果没有属性,则它将是空 Attributes 对象。在 startElement 返回后,此对象的值是未定义的
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
tag=qName;
if ("book".equals(qName)) {
book=new Book();
book.setId(attributes.getValue(0));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
tag="";
if ("book".equals(qName)) {
books.add(book);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String string = new String(ch, start, length);
if ("name".equals(tag)) {//判断当前内容,属于哪一个元素。
book.setName(string);
}else if ("price".equals(tag)) {
book.setPrice(string);
}else if ("author".equals(tag)) {
book.setAuthor(string);
}
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
}
输出结果
书本id :1
书本名字 :编程之美
书本价格 :34.0
书本作者 :《编程之美》小组
书本id :2
书本名字 :平凡的世界
书本价格 :56.0
书本作者 :路遥
DOM
特点:
1. 解析器读入整个文档,然后构建一个驻留内存的树结构
2. 整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;访问效率高。
示例
package com.gz.xml;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomXml {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建一个DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 通过DocumentBuilder对象的parse方法加载xml文件到当前项目
Document document = db.parse("src\\main\\resources\\books.xml");
NodeList bookNodeList = document.getElementsByTagName("book");
List<Book> bookList = new ArrayList<Book>();
for(int i = 0;i < bookNodeList.getLength();i++) {
Node bookNode = bookNodeList.item(i);
Book book = new Book();
// 得到book的属性
NamedNodeMap bookNamedNodeMap = bookNode.getAttributes();
for(int j = 0;j < bookNamedNodeMap.getLength();j++) {
Node bookAttrNode = bookNamedNodeMap.item(j);
String bookAttrName = bookAttrNode.getNodeName();
if("id".equals(bookAttrName)) {
book.setId(bookAttrNode.getNodeValue());
}
}
//解析book节点的子节点
NodeList bookChildNodeList = bookNode.getChildNodes();
for(int z = 0;z < bookChildNodeList.getLength();z++) {
if (bookChildNodeList.item(z).getNodeType() == Node.ELEMENT_NODE) {
Node bookChildNode = bookChildNodeList.item(z);
String bookChildNodeName = bookChildNode.getNodeName();
String bookChildNodeValue = bookChildNode.getFirstChild().getNodeValue();
if("name".equals(bookChildNodeName)) {
book.setName(bookChildNodeValue);
} else if("price".equals(bookChildNodeName)) {
book.setPrice(bookChildNodeValue);
} else if("author".equals(bookChildNodeName)) {
book.setAuthor(bookChildNodeValue);
}
}
}
bookList.add(book);
}
for(Book book : bookList) {
System.out.println("书本id :" + book.getId());
System.out.println("书本名字 :" + book.getName());
System.out.println("书本价格 :" + book.getPrice());
System.out.println("书本作者 :" + book.getAuthor());
System.out.println();
}
}
}
输出结果
书本id :1
书本名字 :编程之美
书本价格 :34.0
书本作者 :《编程之美》小组
书本id :2
书本名字 :平凡的世界
书本价格 :56.0
书本作者 :路遥
备注: Node和Element的关系:
简单的说就是Node是一个基类,DOM中的Element,Text和Comment都继承于> > 它。 换句话说,Element,Text和Comment是三种特殊的Node,它们分别叫做ELEMENT_NODE, TEXT_NODE和COMMENT_NODE。
所以我们平时使用的html上的元素,即Element,是类型为ELEMENT_NODE的Node。
JDOM
特点:
JDOM
优点:①是基于树的处理XML的Java API,把树加载在内存中
②没有向下兼容的限制,因此比DOM简单
③速度快,缺陷少
④具有SAX的JAVA规则
缺点:①不能处理大于内存的文档
②JDOM表示XML文档逻辑模型。不能保证每个字节真正变换。
③针对实例文档不提供DTD与模式的任何实际模型。
④不支持与DOM中相应遍历包
最适合于:JDOM具有树的便利,也有SAX的JAVA规则。在需要平衡时使用
Jar包
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.0</version>
</dependency>
示例
package com.gz.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class JDOMXml {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
File f=new File("src\\main\\resources\\books.xml");
SAXBuilder builder=new SAXBuilder();
List<Book> bookList = new ArrayList<Book>();
try {
Document doc=builder.build(new FileInputStream(f));
Element root=doc.getRootElement();
List<Element> list=root.getChildren("book");
for(int i=0;i<list.size();i++){
Element ele=(Element)list.get(i);
Book book = new Book();
book.setId(ele.getAttribute("id").getValue());
book.setName(ele.getChildText("name"));
book.setPrice(ele.getChildText("price"));
book.setAuthor(ele.getChildText("author"));
bookList.add(book);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (Book book : bookList) {
System.out.println("书本id :" + book.getId());
System.out.println("书本名字 :" + book.getName());
System.out.println("书本价格 :" + book.getPrice());
System.out.println("书本作者 :" + book.getAuthor());
System.out.println();
}
}
}
输出结果
书本id :1
书本名字 :编程之美
书本价格 :34.0
书本作者 :《编程之美》小组
书本id :2
书本名字 :平凡的世界
书本价格 :56.0
书本作者 :路遥
DOM4J
特点:
DOM4J
具有性能优异、灵活性好、功能强大和极端易用的特点是一个开放源代码的软件
Jar包
<dependency>
groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
示例
package com.gz.xml;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class DOM4JXml {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
SAXReader reader=new SAXReader();
List<Book> bookList = new ArrayList<Book>();
try {
Document doc=reader.read(new FileInputStream(new File("src\\main\\resources\\books.xml")));
Element root=doc.getRootElement();
Iterator<Element> it=root.elementIterator();
while(it.hasNext()){
Element ele=(Element)it.next();
Book book = new Book();
book.setId(ele.attributeValue("id"));
book.setName(ele.elementText("name"));
book.setPrice(ele.elementText("price"));
book.setAuthor(ele.elementText("author"));
bookList.add(book);
System.out.println(ele.elementText("name")+"---"+ele.elementText("age"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
for (Book book : bookList) {
System.out.println("书本id :" + book.getId());
System.out.println("书本名字 :" + book.getName());
System.out.println("书本价格 :" + book.getPrice());
System.out.println("书本作者 :" + book.getAuthor());
System.out.println();
}
}
}
输出结果
书本id :1
书本名字 :编程之美
书本价格 :34.0
书本作者 :《编程之美》小组
书本id :2
书本名字 :平凡的世界
书本价格 :56.0
书本作者 :路遥