XML文件解析之--DOM与SAX

xml文件又称‘可扩展性标记语言’,能够对文档和数据进行结构化处理,从而可以在部门、客户和供应商之间进行交换,实现动态内容生成,企业集成和应用开发。web

咱们在进行web开发的时候离不开xml文件,xml文件无处不在,此次就烂讨论一下xml经常使用的解析方法及其CRUD操做,欢迎你们交流指正。ide

 

咱们先来看看两种解析方式的过程,比较一下他们的优劣之处。函数

 

SAX解析方式:它对xml文档进行逐行扫描,一边扫描一边解析。当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数作相应动做,而后继续一样的扫描,直至文档结束。工具

DOM解析方式:DOM解析是W3C组织提供的标准,把全部内容一次性的装载入内存,并构建一个驻留在内存中的树状结构,而后根据节点之间的关系来解析XML。性能

 

性能分析:this

1.SAX解析由于是逐行逐句扫描解析,比起DOM方式一次性装在全部内容到内存中来讲,效率来讲应该更高一些。编码

2.可是偏偏是SAX这种解析方式,注定使SAX解析不适合对XML文档进行增删改等操做。而DOM解析的增删改操做相比之下就十分方便。spa

3.由于DOM解析式一次性装在全部内容到内存中,因此若是用户只须要其中一部份内容,DOM解析的方式的效率就大打折扣。code

 

综上分析:sax解析更适合作部分信息的读取操做,DOM解析更适合作XML文件的增删改操做。orm

 

 

接下来咱们来看看它们的CRUD操做

xml文件:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE books SYSTEM "theBook.dtd">
<books>
    <book>
        <id>01</id>
        <name>鲁滨逊漂流记</name>
        <price>33</price>
    </book>
    <book>
        <id>02</id>
        <name>钢铁是怎样炼成的</name>
        <price>30</price>
    </book>
</books> 
复制代码

 

对应的Bean类

复制代码
public class Book {
    private String id;
    private String name;
    private String price;
    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;
    }
    
}
复制代码

1.SAX解析:

流程:

1.获取工厂实例;

2.获得解析器;

3.获得读取器;

4.设置内容处理器;(SAX解析方式给咱们提供了不一样的处理器接口以及父类,咱们能够选择继承其中的父类或者实现接口进行内容处理)

在进行内容处理时,SAX提供了多种不一样的方法,分别在文档的开始和结尾,元素的开始和结尾等有事件,咱们须要在相应的地方重写这些事件完成功能。

5.最后咱们将相应的对象模型设置属性,将其存入list中,返回list。

解析实例:

复制代码
public void saxFactory() throws ParserConfigurationException, SAXException, IOException{
        //得到工厂实例
        SAXParserFactory ft = SAXParserFactory.newInstance();
        //获得解析器
        SAXParser sp = ft.newSAXParser();
        //获得读取器
        XMLReader reader = sp.getXMLReader();
        //设置内容处理器
        BeanListHandler handler = new BeanListHandler();
        
        reader.setContentHandler(handler);
        
        reader.parse("src/Book.xml");
        
        List <Book> list = handler.getList();
}
复制代码

BeanListHandler类

复制代码
class BeanListHandler extends DefaultHandler{
     private List list = new ArrayList();
     private String currentTag;
     private Book book;
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        if("name".equals(currentTag)){
            String name = new String(ch,start,length);
            book.setName(name);
        }
        if("id".equals(currentTag)){
            String id = new String(ch,start,length);
            book.setId(id);
        }
        if("price".equals(currentTag)){
            String price = new String(ch,start,length);
            book.setPrice(price);
        }
        super.characters(ch, start, length);
    }
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // TODO Auto-generated method stub
        if(qName.equals("book")){
            list.add(book);
            book = null;
        }
        currentTag = null;
        super.endElement(uri, localName, qName);
    }
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        currentTag = qName;
        if("book".equals(currentTag)){
            book = new Book();
        }
        super.startElement(uri, localName, qName, attributes);
    }
    public List getList() {
        return list;
    }
}
复制代码

SAX解析:相对使用起来复杂一些,主要是实现步骤顺序,以及相对应事件中填入实现功能代码。

 

2.DOM解析:

DOM解析的实现代码相对于前者就简单易懂些

DOM解析中有多种解析工具,此处以DOM4j为例

主要步骤:

1.得到读取器

2.得到document对象

3.对相应的节点对象进行操做

读取操做(获取某个节点的值):

复制代码
public void read() throws DocumentException{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/Book.xml"));
        
        Element root = document.getRootElement();
        Element book = (Element)root.elements("book").get(1);
        System.out.println(book.element("name").getText());
    }
复制代码

增长操做:

复制代码
public void add() throws DocumentException, IOException{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/Book.xml"));
        
        Element book = document.getRootElement().element("book");
        book.addElement("author").setText("abc");
        
        //格式化输出器 
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format);

        writer.write(document);
        writer.close();
    }
复制代码

删除操做:

复制代码
public void delete() throws DocumentException, IOException{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/Book.xml"));
        
        Element root = document.getRootElement();
        Element name = root.element("book").element("name");
        
        name.getParent().remove(name);
        
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format); 
        writer.write(document);
        writer.close();
    }
复制代码

修改操做:

复制代码
public void update() throws DocumentException, IOException{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/Book.xml"));
        
        Element root = document.getRootElement();
        Element book = (Element) root.elements("book").get(1);
        book.element("name").setText("西游记");
        
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/Book.xml"),format); 
        writer.write(document);
        writer.close();
    }
复制代码

!!此处须要注意:也许你们注意到了增删改后面有五行代码是同样的。没错!由于须要对xml文件进行读写,因此也须要解决乱码问题,解决乱码问题有多种方法,此处只列举这一种方法,建立格式化输出器,规定其编码和xml中默认相同的编码,输出时选用字节流,配合格式化输出器中规定的编码,这样就不会产生中文乱码问题了。

相关文章
相关标签/搜索