SAX解析
SAX允许在读取XML文档时就对文档进行处理,而不必等到整个文档装载完才会进行操作。
SAX采用事件处理的方式解析XML文件,利用SAX解析XML文档,比较重要的两个点是解析器和事件处理器。
SAX解析XML文档步骤
- 创建解析工厂;
- 得到解析器 ;
- 获取读取器;
- 设置内容处理器;
- 读取XML文档
实际案例
book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书><书名 aa="bbb">Android技术开发大全</书名>
<作者>Michael Main</作者>
<售价>59</售价>
</书>
<书>
<书名>Effective Java</书名>
<作者>Ed Burnette</作者>
<售价>68</售价>
</书>
</书架>
用SAX解析book.xml文档,并用JavaBean封装
package cn.moving.parseXml;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParse2 {
public static void main(String args[]) throws Exception, SAXException {
// 创建解析工厂
SAXParserFactory sf = SAXParserFactory.newInstance();
// 创建解析工厂得到解析器 获取读取器设置内容处理器读取XML文档
SAXParser parser = sf.newSAXParser();
// 获取读取器
XMLReader reader = parser.getXMLReader();
// 设置内容处理器
reader.setContentHandler(new Handler());
// 读取XML文档
reader.parse("src/book.xml");
}
}
class Handler extends DefaultHandler {
private String currentTag ;
private int needNumber = 2;
private int currentNumber = 1;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
if (("作者".equals(currentTag) )) {
currentNumber++;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(currentNumber == 2&¤tTag.equals("作者")){
System.out.println(new String(ch, start, length));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
}
}
将解析出来的节点,用JavaBean对象封装起来,便于进行持久操作
package cn.moving.parseXml;
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.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class SAXAndBean {
public static void main(String args[]) throws Exception, SAXException {
// 创建解析工厂
SAXParserFactory sf = SAXParserFactory.newInstance();
// 得到解析器
SAXParser parser = sf.newSAXParser();
// 获取读取器
XMLReader reader = parser.getXMLReader();
// 设置内容处理器
BeanListHandler lh = new BeanListHandler();
reader.setContentHandler(lh);
// 读取XML文档
reader.parse("src/cn/moving/parseXml/outbook.xml");
List<Book> books = lh.getBooks();
System.out.println(books);
}
}
class BeanListHandler extends DefaultHandler {
private List<Book> list = new ArrayList<Book>();
private Book book;
private String currentTag;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
if (("书".equals(currentTag))) {
book = new Book();
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (("书名").equals(currentTag)) {
book.setName(new String(ch, start, length));
}
if (("作者").equals(currentTag)) {
book.setAuthor(new String(ch, start, length));
}
if (("售价").equals(currentTag)) {
book.setPrice(new String(ch, start, length));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTag = null;// /
if (("书").equals(qName)) {
list.add(book);
book = null;
}
}
public List<Book> getBooks() {
return list;
}
}
JavaBean
package cn.moving.parseXml;
public class Book {
private String name ;
private String author;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
JAXP解析
用JAXP解析的步骤
- 调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂
- 调用工厂对象的newDocumentBuilder方法得到DOM解析器对象
- 调用DOM解析器对象的parse()方法解析XML文档,得到代表整个文档的Document对象
- 进行可以利用DOM特性对整个XML文档进行操作了
对XML文档进行增删改查
package cn.moving.parseXml;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ParseXml {
/**
* 使用dom方式对XML文档进行增删改查
*
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
@Test
// 读取<书名>Adroid基础教程</书名>
public void read() throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
NodeList list = document.getElementsByTagName("书名");
Node node = list.item(0);
String content = node.getTextContent();
System.out.println(content);
}
@Test
// 得到文档中所有标签
public void readAll() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
NodeList list = document.getElementsByTagName("书名");
Node root = document.getElementsByTagName("书架").item(0);
list(root);// ??????????????
}
private void list(Node node) {
if (node instanceof Element) {
System.out.println(node.getNodeName());
}
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node child = list.item(i);
list(child);
}
}
@Test
// 读取<书名 name=Data Structures"">数据结构(Java语言描述)</书名>
public void readAttribute() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
NodeList list = document.getElementsByTagName("书名");
Element element = (Element) list.item(0);
// Element是Node的子类,所以有更多的方法
String value = element.getAttribute("name");
System.out.println(value);
/*
* //笨办法 Node node = list.item(0); if (node.hasAttributes()) {
* NamedNodeMap map = node.getAttributes(); for (int i = 0; i <
* map.getLength(); i++) { Node nd = map.item(i); String name =
* nd.getNodeName(); // nd.getNodeType() String value =
* nd.getNodeValue(); System.out.println(name + ":" + value); } }
*/
}
@Test
// 添加节点<售价>$10</售价>
public void add() throws ParserConfigurationException, SAXException,
IOException, Exception, TransformerFactoryConfigurationError {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
Element element = document.createElement("售价");
element.setTextContent("99元");
document.getElementsByTagName("书").item(0).appendChild(element);
// 更新内存中数据,将内存中数据写入XML文件中
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
DOMSource source = new DOMSource(document);
FileOutputStream fos = new FileOutputStream(new File(
"src/cn/moving/parseXml/outbook.xml"));
StreamResult result = new StreamResult(fos);
transformer.transform(source, result);
fos.flush();
fos.close();
}
@Test
// 指定位置添加节点:给<售价>56</售价>前加<售价>100</售价>
public void addAppoint() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
// 得到参考节点(书名)
Element refNode = (Element) document.getElementsByTagName("售价").item(0);
// 创建一个新节点
Element element = document.createElement("价格");
//element.setNodeValue("100元");//wrong
element.setTextContent("100元");
//连接节点
Element e = (Element)document.getElementsByTagName("书").item(0);
e.appendChild(element);
e.insertBefore(element, refNode);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/cn/moving/parseXml/outbook2.xml")));
}
@Test
// 删除节点<售价>10</售价>
public void delete() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/outbook.xml");
Node price = document.getElementsByTagName("售价").item(0);
price.getParentNode().removeChild(price);
DOMSource source = new DOMSource(document);
// StreamResult os = new StreamResult(new File("src/cn/moving/parseXml/outbook.xml"));//true
StreamResult os = new StreamResult(new FileOutputStream("src/cn/moving/parseXml/outbook.xml"));
TransformerFactory.newInstance().newTransformer().transform(source, os);
}
@Test
// 更新售价
public void update() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/cn/moving/parseXml/book.xml");
Node bookName = document.getElementsByTagName("书").item(0).getFirstChild();
bookName.setTextContent("Android技术开发大全");
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/cn/moving/parseXml/book.xml")));
}
}
Dom4J解析XML
Dom4J解析XML文件是DOM解析中最好用的一种方法,只需导入Dom4J的jar包即可
package cn.moving.parseXml;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
public class Dom4jParse {
@Test
public void read() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(
"src/cn/moving/parseXml/book.xml"));
Element books = document.getRootElement();
Element e = (Element) books.elements().get(0);
Element bookName = e.element("书名");
System.out.println(bookName.getText());
Attribute attr = bookName.attribute("name");
System.out.println(attr.getText());
}
@Test
public void add() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cn/moving/parseXml/book.xml");
Element book = (Element) document.getRootElement().element("书");
book.addElement("出版社").setText("人民邮电出版社");
OutputFormat format = OutputFormat.createCompactFormat();
// OutputFormat format = new OutputFormat();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream(
"src/cn/moving/parseXml/outbook2.xml"));
// 漂亮格式输出
// XMLWriter writer = new XMLWriter(new
// FileOutputStream("src/cn/moving/parseXml/outbook2.xml"), format);
writer.write(document);
writer.close();
}
@Test
//往指定位置添加元素
public void addAppoint() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cn/moving/parseXml/book.xml");
Element book = (Element) document.getRootElement().element("书");
List list = book.elements();//[书名,作者,价格]
Element e = DocumentHelper.createElement("折扣");
e.setText("7折");
list.add(2,e);
OutputFormat format = OutputFormat.createCompactFormat();
// OutputFormat format = new OutputFormat();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream(
"src/cn/moving/parseXml/outbook2.xml"));
// XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/outbook2.xml"), format);
writer.write(document);
writer.close();
}
@Test
// 删除节点<售价>10</售价>
public void delete() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cn/moving/parseXml/book.xml");
Element element = document.getRootElement().element("书").element("售价");
element.getParent().remove(element);
XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/book.xml"));
writer.write(document);
writer.close();
}
@Test
// 更新售价
public void update() throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/cn/moving/parseXml/book.xml");
Element element = document.getRootElement().element("书").element("售价");
element.setText("59");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/cn/moving/parseXml/book.xml"));
writer.write(document);
writer.close();
}
@Test
//Powerful Navigation with XPath
public void xpath() throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/cn/moving/parseXml/book.xml"));
String value = document.selectSingleNode("//作者").getText();
Node node = document.selectSingleNode("//书名[@aa='bbb']");
String bookName = document.selectSingleNode("//书名[@aa='bbb']").getText();
String attrValue = node.valueOf("@aa");
System.out.println(value);
System.out.println(attrValue);
System.out.println(bookName);
}
}