1 SAX
- 在使用DOM解析XML文档的时候,需要读取整个XML文档,在内存中构架代表整个DOM树的Document对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
- SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才对文档进行操作。
- SAX采用事件处理的方式解析XML文件,利用SAX解析XML文档,涉及两个部分:解析器和事件处理器:
- 解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
- 解析器采用SAX方式在解析某个XML文档的时候,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方式时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
- 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松的得到SAX解析器解析到的数据,从而可以决定如何对数据进行处理。
- 示例:通过SAX解析xml文档,并将数据封装到javabean中
<?xml version="1.0" encoding="UTF-8" standalone="no"?><书架>
<书>
<书名>java从入门到放弃</书名>
<作者>呵呵</作者>
<售价>0.01</售价>
</书>
<书>
<书名>c从入门到精通</书名>
<作者>我好</作者>
<售价>1.00</售价>
</书>
</书架>
package com;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 2017/10/28
* 说明:
*/
public class SAXDemo {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
List<Book> books = new ArrayList<>();
//使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
//通过SAX解析工厂得到解析对象
SAXParser sp= spf.newSAXParser();
//通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
//设置读取器的事件处理器
xmlReader.setContentHandler(new DefaultHandler(){
private Book book = null;
private String currentTagName;//当前读取的元素的名称
public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException {
if("书".equals(qName)){
book = new Book();
}
currentTagName = qName;
}
public void endElement (String uri, String localName, String qName) throws SAXException {
if("书".equals(qName)){
books.add(book);//读到书标记的结束,把书对象存起来
}
currentTagName = null;
}
public void characters (char ch[], int start, int length) throws SAXException {
if("书名".equals(currentTagName)){
book.setName(new String(ch,start,length));
}
if("作者".equals(currentTagName)){
book.setAuthor(new String(ch,start,length));
}
if("售价".equals(currentTagName)){
book.setPrice(new String(ch,start,length));
}
}
});
//解析xml文件
xmlReader.parse("D:\\code\\web\\src\\main\\webapp\\book.xml");
for(Book b:books){
System.out.println(b);
}
}
}
2 DOM4j
- dom4j是一个简单、灵活的开发源代码的库。dom4j是由早起开发jdom的人分离出来而后独立开发的。与jdom不同的是,dom4j使用接口和抽象类,虽然dom4j的API相对复杂一些,但它提供了比jdom更好的灵活性。
- dom4j是一个非常优秀的java XML API,并且性能优异、功能强大和极其使用的特点。
2.1 Document对象
- 在dom4j中,获取Document对象的方式有三种:
- ①读取xml文件,获取Document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("book.xml"));
String text = "<member></member>";
Document document = DocumentHelper.parseText(text);
Document document = DocumentHelper.createDocument();
Element root = document.addElement("member");
2.2 节点对象
Element root = document.getRootElement();
Element element=node.element(“书名");
String text=node.getText();
- 取得某个节点下的所有名为"member"的子接单,并进行遍历
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
Element ageElm = newMemberElm.addElement("age");
parentElm.remove(childElm);
2.3 节点属性
Element root=document.getRootElement();
Attribute attribute=root.attribute("size");
String text = attribute.getText();
Attribute attribute=root.attribute("size");
root.remove(attribute);
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
newMemberElm.addAttribute("name", "sitinspring");
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
2.4 将文档写入xml文件
XMLWriter writer = new XMLWriter(new FileWriter("output.xml")); writer.write(document);
writer.close();
OutputFormat format = OutputFormat.createPrettyPrint();
// 指定XML编码
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream ("output.xml"),format);
writer.write(document);
writer.close();
2.5 在指定位置插入节点
- ①得到插入位置的节点列表
- ②调用add(index,element),由index决定element的插入位置
- ③element元素可以通过DocumentHelper对象得到
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");
List list = root.element("书").elements();
list.add(1, aaa);
//更新document