• XML文件解析之--DOM与SAX


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

    我们在进行web开发的时候离不开xml文件,xml文件无处不在,这次就烂讨论一下xml常用的解析方法及其CRUD操作,欢迎大家交流指正。

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

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

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

    性能分析:

    1.SAX解析因为是逐行逐句扫描解析,比起DOM方式一次性装在所有内容到内存中来说,效率来说应该更高一些。

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

    3.因为DOM解析式一次性装在所有内容到内存中,所以如果用户只需要其中一部分内容,DOM解析的方式的效率就大打折扣。

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

    接下来我们来看看它们的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中默认相同的编码,输出时选用字节流,配合格式化输出器中规定的编码,这样就不会产生中文乱码问题了。

  • 相关阅读:
    产品列表
    PHP全栈学习笔记5
    PHP全栈学习笔记5
    PHP全栈学习笔记4
    更新YUM源后的arning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY错误
    监听EditText输入完成
    关于PHP接收HTTP模拟POST传JSON格式时$_POST为空的问题
    安卓时间类型的转换和比大小
    Android之观察者/被观察者模式Observer/Observable
    WKWebView--JS调用OC的方法
  • 原文地址:https://www.cnblogs.com/efforts-will-be-lucky/p/7602508.html
Copyright © 2020-2023  润新知