XML解析方式

XML是一种非常常见的数据存储方式,有四种解析方式,DOM、SAX、JDOM、DOM4J四种解析方式。其中DOM、SAX是Java中自带的,JDOM、DOM4J需要添加jar包。
接着就是对这四种XML文件解析方式进行总结。

XML解析


1.SAX

    /**
     * 通过SAX方法对XML文件进行解析
     * 基于事件驱动的一种解析方式
     * 优点:
     *         适用于只需处理xml中的数据时
     *         事件驱动,内存耗费少
     * 缺点:
     *         不易编码
     *         一般不能同时访问到同一个xml文件中的多处数据
     * 用法:新建一个类继承自DefalutHandler并重写5个方法
     * 调用顺序 :
     *             statrDocument()在解析开始时调用
     *             startElement()在开始解析到节点开始标签时调用
     *             characters()在解析到节点之间的内容时调用
     *             endElement()在解析到节点结束便签时调用
     *             endDoucument()在解析结束时调用
     */
    public static void parseXMLBySAX(String path) {
        //创建SAXParserFactory对象
        SAXParserFactory factor=SAXParserFactory.newInstance();
        try {
            //通过SAXParserFactory创建出SAXParser的对象
            SAXParser parser=factor.newSAXParser();
            //创建出DefaultHandler继承类的对象
            SAXHandler handler=new SAXHandler();
            try {
                //进行解析
                parser.parse(path, handler);
                for (Book book : handler.bookList) {
                    System.out.println(book.toString());
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public class SAXHandler extends DefaultHandler {
        int bookNumber=1;
        Book book;
        List bookList=new ArrayList();
        String value;
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            // TODO Auto-generated method stub
            super.startElement(uri, localName, qName, attributes);
            if(qName.equals("Book")) {
                System.out.println("开始解析第"+bookNumber+"本书");
                bookNumber++;
                int number=attributes.getLength();
                book=new Book();
                for (int i = 0; i < number; i++) {
                    System.out.println(attributes.getQName(i)+"="+attributes.getValue(i));
                    book.setId(attributes.getValue(i));
                }
            }else if(!qName.equals("Book")&&!qName.equals("BookStore")) {
                System.out.print(qName+":");
            }

        }
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            // TODO Auto-generated method stub
            super.endElement(uri, localName, qName);
            if(qName.equals("Book")) {
                bookList.add(book);
                book=null;
            }else if(qName.equals("name")) {
                book.setName(value);
            }else if (qName.equals("price")) {
                book.setName(value);
            }else if (qName.equals("author")) {
                book.setAuthor(value);
            }
        }
        @Override
        public void startDocument() throws SAXException {
            // TODO Auto-generated method stub
            super.startDocument();
            System.out.println("---------------开始解析-----------------");
        }
        @Override
        public void endDocument() throws SAXException {
            // TODO Auto-generated method stub
            super.endDocument();
            System.out.println("------------结束解析-----------------------");
        }
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            // TODO Auto-generated method stub
            super.characters(ch, start, length);
            value=new String(ch,start,length);
            if(!value.trim().equals("")) {
                System.out.println(value);
            }
        }
    }
    

2.DOM

    /**
     * 通过DOM解析XML文件
     * 优点:
     *         形成树结构,直观好理解,便于代码修改
     *         解析过程中树结构保存在内存中,方便修改
     * 缺点:
     *         当xml文件太大时,会耗损大量内存,导致内存溢出
     */
    public static void parseXMLByDom(String path) {
        //创建DocumentBuilderFactory的对象
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        try {
            //通过DocumentBuilderFactory对象创建出DocumentBuilder对象
            DocumentBuilder builder=factory.newDocumentBuilder();
            Document document;
            try {
                //通过DocumentBuilder对象进行解析 返回值为Document
                document = builder.parse(path);
                //得到Book节点
                NodeList list=document.getElementsByTagName("Book");
                for (int i = 0; i < list.getLength(); i++) {
                    //
                    Node node=list.item(i);
                    //获得Book节点的子节点
                    NodeList childList=node.getChildNodes();
                    for (int j = 0; j < childList.getLength(); j++) {
                        Node childNode=childList.item(j);
                        //判断空格
                        if (childNode.getNodeType()==Node.ELEMENT_NODE) {
                            System.out.println(childNode.getNodeName()+"="+childNode.getFirstChild().getNodeValue());
                        }
                    }
                }
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    

3.JDOM

    /**
     * 使用JDOM进行XML类型数据进行解析
     * 需要添加Jar包
     * 优点:
     *         大量使用具体类而不是接口
     *         API大量使用Collections类 熟悉Collections类可以很方便
     */
    public static void parseXMLByJDOM(String path) {
        SAXBuilder build=new SAXBuilder();
        Book book;
        List bookListEntity=new ArrayList();
        try {
            InputStream in=new FileInputStream(path);
            org.jdom2.Document document=build.build(in);
            //获取根节点BookStore节点
            Element rootElement= document.getRootElement();
            //获取根节点的子节点Book节点
            List bookList=rootElement.getChildren();
            //解析Book节点
            for (Element element:bookList) {
                System.out.println("开始解析第"+(bookList.indexOf(element)+1)+"本书");
                book=new Book();
                //解析Book节点的属性
                List childAttribute=element.getAttributes();
                //解析Book节点的属性和名称
                for (Attribute attribute : childAttribute) {
                    System.out.println(attribute.getName()+"="+attribute.getValue());
                    book.setId(attribute.getValue());
                }
                //解析Book节点的子节点
                List childList=element.getChildren();
                for (Element element2 : childList) {
                    String strName=element2.getName();
                    String strValue=element2.getValue();
                    System.out.println(strName+"="+strValue);
                    if(strName.equals("name")) {
                        book.setName(strValue);
                    }else if(strName.equals("author")) {
                        book.setAuthor(strValue);
                    }else if(strName.equals("price")) {
                        book.setPrice(strValue);
                    }
                }
                bookListEntity.add(book);
                book=null;
                System.out.println("结束解析第"+(bookList.indexOf(element)+1)+"本书");
            }
            System.out.println("-------------------------------------------------------------");
            for (Book bookEntity : bookListEntity) {
                System.out.println(bookEntity.toString());
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    


4.DOM4J



/**

 * 使用DOM4J对XML类型数据进行解析
 * 需要添加Jar包
 * 优点:    
 *         JDOM的智能分支合并了许多超出XML文档表示的功能
 *         使用接口和抽象类
 *         开源    
 */
public static void parseXMLByDOM4J(String path) {
    SAXReader reader=new SAXReader();
    ArrayList<Book> bookEntityList=new ArrayList();
    Book bookEntity;
    try {
        org.dom4j.Document document=reader.read(new File(path));
        org.dom4j.Element bookStore=document.getRootElement();
        Iterator it=bookStore.elementIterator();
        int i=1;
        while(it.hasNext()) {
            System.out.println("开始解析第"+i+"本书");
            bookEntity=new Book();
            org.dom4j.Element book=(org.dom4j.Element) it.next();
            List<org.dom4j.Attribute> attributes=book.attributes();
            for (org.dom4j.Attribute attr : attributes) {
                System.out.println(attr.getName()+"="+attr.getValue());
                bookEntity.setId(attr.getValue());
            }
            Iterator bookIt=book.elementIterator();
            while(bookIt.hasNext()) {
                org.dom4j.Element bookChildElement=(org.dom4j.Element) bookIt.next();
                String bookChildName=bookChildElement.getName();
                String bookChildValue=bookChildElement.getStringValue();
                if(bookChildName.equals("name")) {
                    bookEntity.setName(bookChildValue);
                }else if(bookChildName.equals("price")) {
                    bookEntity.setPrice(bookChildValue);
                }else if(bookChildName.equals("author")) {
                    bookEntity.setAuthor(bookChildValue);
                }
                System.out.println(bookChildName+"="+bookChildValue);
            }
            bookEntityList.add(bookEntity);
            bookEntity=null;
            System.out.println("结束解析第"+i+"本书");
            i++;
        }
        System.out.println("---------------------------------------------------------");
        for (Book book : bookEntityList) {
            System.out.println(book.toString());
        }
    } catch (DocumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}</pre>