XML解析

1.最基础的方法SAX解析和DOM解析。   

     DOM 是基于Document对象.在解析是把整个文件加载到内存中.只要电源不断.文档始终在内存中,

         进行遍历查找比较方便.但是整个文档的加载需要消耗的很多内存和时间.

     SAX.因为Document的耗时.使用基于事件-驱动的模型,只需要加载部分内容.在遍历上比较慢.

2.具体方法 sax解析:

  思路:1.得到saxParse对象  使用parse 

           2.得到继承了DefaultHandle 的对象来处理xml文件。继承的对象需要重写其中5个方法,当然实际上是4个。

           3.由于需要得到具体的数据,于是需要在Handle的子对象中加入List  StringBuilder等。

实现第一步:

  public List<Book> parserXMLBySax(File file) throws ParserConfigurationException, SAXException, IOException {

        //--1.创建解析工厂类对象
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //--2.通过工厂获取解析器对象
        SAXParser parser = factory.newSAXParser();
        //--3.解析器调用方法解析file
        parser.parse(file, mHandler);
        return mHandler.getBookList();
    }

实现第二,,三步:

class MyHandler extends DefaultHandler {

    private List<Book> mList;// 得到集合
    private Book mBook;
    private StringBuilder mStringBuilder;//用来存储具体的数据

    public List<Book> getBookList() {
        return mList;
    }

    /**
     * 初始化集合和存储节点值的StringBuilder对象
     *
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        mList = new ArrayList<>();
        mStringBuilder = new StringBuilder();
    }

    /**
     * ns NameSpace
     * <book xmlns:baidu="www.baidu.com">  xmlns  是命名空间相当于 java中的packager
     * <p>
     * <baidu:tieba baidu:gem="tieba.baidu.com/gem">宝石</baidu:tieba>
     * <p>
     * <p>
     * </book>
     *
     * @param uri        uri指向命名空间的字符串.当命名空间没有指明时该值为空字符串
     * @param localName  本地名称 当没有前缀(:之前的内容)时该值为空字符串
     * @param qName      限制的 可以理解为包含前缀的localName 当属性不存在时,返回空字符串
     * @param attributes 属性集
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);

        if (qName.equals("book"))
            mBook = new Book();
        mStringBuilder.setLength(0);//--把长度设置为0,以便开始记录新的内容.这里除了使用StringBuilder还可以使用
//        Stack<String> stack = new Stack<>(); //-- 这里添加,end的时候移除

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        switch (qName) {
            case "id":
                mBook.setId(Integer.parseInt(mStringBuilder.toString()));
                break;
            case "name":
                mBook.setName(mStringBuilder.toString());
                break;
            case "book":
                mList.add(mBook);
                break;
            default:
                break;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        mStringBuilder.append(ch, start, length);
    }
}

3.Dom解析

  思路:1.得到document 

           2.得到主根节点 getDocumentElement  然后就是得到子节点,一层一层的匹配。

实现第一步:

public List<Book> parserXMLByDom(File file) throws ParserConfigurationException, IOException, SAXException {
        List<Book> tList = new ArrayList<>();
        //--1.获取DocumentBuilderFactory
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //--2.获取DocumentBuilder对象.在构建解析器对象时会产生配置异常
        DocumentBuilder builder = factory.newDocumentBuilder();
        //--3.使用parser方法解析文件.获取Document对象
        Document document = builder.parse(file);//org.w3c.document包
        //--4.获取Document中的元素
        Element element = document.getDocumentElement();

实现第二步:

  //--5.通过元素获取节点的集合
        NodeList items = element.getElementsByTagName("book");
        //--6.遍历节点
        for (int i = 0 ;i < items.getLength() ;i ++ ){
            Book book = new Book();
            //--7.取出所有的子节点
            Node item = items.item(i);
            NodeList childNode = item.getChildNodes();
            for (int j = 0 ; j < childNode.getLength() ; j ++){
                //--取出节点
                Node node = childNode.item(j);
                //--取出节点的名称
                String nodeName = node.getNodeName();
                //--匹配nodeName
                switch (nodeName){
                    default://--永远要加
                        break;
                    case "id":
                        book.setId(Integer.parseInt(node.getFirstChild().getNodeValue()));
                        break;
                    case "name":
                        book.setName(node.getFirstChild().getNodeValue());
                        break;
                }
            }//--内层循环是生成一个Book对象.外层循环是有多少个Book对象
            tList.add(book);
        }
        return tList;
    }

 

posted on 2016-08-19 16:52  青木堂  阅读(224)  评论(0)    收藏  举报

导航