继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

XML之SAX方式读写文件

亚努人
关注TA
已关注
手记 20
粉丝 36
获赞 349

SAX是基于事件驱动的方式,一条一条的读写文件,从而触发相关方法。由于它不像DOM方式一样,将整个文档加载后再进行解析,所以对内存的耗费较少,生成和解析的速度非常快,适用于只需要处理XML中的数据时,但不适用同时访问同一个XML中的不同数据。

一、SAX解析XML文件
1.1 解析准备
1、获取SAXParserFactory的实例factory;
2、通过factory获取SAXParser的实例parser;
3、创建一个SAXParserHandler对象handler,通过parser的parse方法进行解析。
1.2 解析过程
1、创建SAXParserHandler类,并继承DefaultHandler类;
2、重写startDocument方法,标识解析开始;
3、重写startElement方法,遍历文件的开始标签;
4、若需要获取节点值,则要重写characters(char ch[],int start,int length)方法;
5、重写endElement()方法结束遍历标签;
6、重写endDocument()方法结束解析文档。
1.3 将解析内容存储到对象
1、新建对象类,设置好属性和setter/getter方法;
2、在解析的方法里,利用setter方法将内容传入对象。
public class Book {
    private String id;
    private String name;
    private String author;
    private String year;
    private String price;
    private String language;
    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 getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getYear() {
        return year;
    }
    public void setYear(String year) {
        this.year = year;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public String getLanguage() {
        return language;
    }
    public void setLanguage(String language) {
        this.language = language;
    }   
}
public ArrayList<Book> parseXML() throws Exception, SAXException {
        // 获取SAXParserFactory的实例
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 获取SAXParser实例parser
        SAXParser parser = factory.newSAXParser();
        // 创建一个SAXParserHandler对象
        SAXParserHandler handler = new SAXParserHandler();
        parser.parse("books.xml", handler); // 开始进行解析

        System.out.println("书的数目:" + handler.getBooklist().size());
        for (Book book : handler.getBooklist()) {
            System.out.println(book.getId() + " " + book.getAuthor() + " " + book.getName() + "  " + book.getPrice()
                    + " " + book.getYear() + " " + book.getLanguage());
            System.out.println("------------------");
        }
        return handler.getBooklist();
    }
public class SAXParserHandler extends DefaultHandler {
    int bookIndex; //定义全局变量,用于给书计数
    String value = null;
    Book book = null;
    private ArrayList<Book> booklist = new ArrayList<Book>();
    public ArrayList<Book> getBooklist() {
        return booklist;
    }
    public void setBooklist(ArrayList<Book> booklist) {
        this.booklist = booklist;
    }

    //以下方法均通过Alt+/进行重载,分别用来遍历文件的开始标签和结束标签
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        //解析book标签
        if(qName.equals("book")){
            bookIndex++;
            book = new Book();
            System.out.println("=====开始遍历第"+bookIndex+"本书的内容=====");
            //若已知book下属性的名称为id,获取属性值的方法如下
            //System.out.println("book的属性值是:"+attributes.getValue("id"));
            //若不知book下的属性名称个数和值,则使用循环进行遍历
            for(int i=0;i<attributes.getLength();i++){
                System.out.print("属性名是:"+attributes.getQName(i));
                System.out.println("--->属性值是:"+attributes.getValue(i));
                if("id".equals(attributes.getQName(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 {
        super.endElement(uri, localName, qName);
        if(qName.equals("book")){
            booklist.add(book);
            book = null;
            System.out.println("=====结束遍历第"+bookIndex+"本书的内容=====");
        }else if(qName.equals("name")){
            book.setName(value);
        }else if(qName.equals("author")){
            book.setAuthor(value);
        }else if(qName.equals("year")){
            book.setYear(value);
        }else if(qName.equals("price")){
            book.setPrice(value);
        }else if(qName.equals("language")){
            book.setLanguage(value);
        }
    }

    //以下两个方法用来标识解析开始和结束
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        System.out.println("begin!");
    }
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("end!");
    }

    //获取节点值,ch字符数组是整个xml文本的内容,start是开始节点的位置,length为长度
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        value = new String(ch,start,length);
        if(!value.trim().equals("")){ //把空格和换行节点去掉
            System.out.println("节点值是:"+value);
        }
    }
}
二、SAX生成XML文件
2.1 XML文档生成
1、创建SAXTransformerFactory对象tff;
2、通过tff创建一个TransformerHandler对象handler;
3、通过Handler创建Transformer对象tr;
4、利用tr可对XML文档格式进行设置;
5、创建一个result对象,与handler相关联。
2.2 XML文档内容的生成
public void createXML() throws SAXException, Exception{
        ArrayList<Book> bookList = parseXML();
        //生成XML文件,1、创建一个SAXTransformerFactory的对象
        SAXTransformerFactory tff = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        //2、通过SAXtransformerFactory对象创建一个TransformerHandler的对象
        TransformerHandler handler = tff.newTransformerHandler();
        //3、通过Handler对象创建一个Transformer对象
        Transformer tr = handler.getTransformer();
        //4、通过Transformer对象对生成的XML文件进行设置
        tr.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        tr.setOutputProperty(OutputKeys.INDENT, "yes");
        //5、创建一个result对象,并与Handler关联
        File file = new File("books2.xml");
        if(!file.exists()){
            file.createNewFile();
        }
        Result result = new StreamResult(new FileOutputStream(file));
        handler.setResult(result);

        //利用Handler对象进行XML文件内容的编写
        //打开document
        handler.startDocument();
        AttributesImpl atts = new AttributesImpl();
        handler.startElement("", "", "bookstore", atts);
        for(Book book:bookList){
            atts.clear();
            atts.addAttribute("", "", "id", "", book.getId());
            handler.startElement("","","book",atts);
            //创建name子节点
            if(book.getName()!=null && !book.getName().trim().equals("")){      
                atts.clear();
                handler.startElement("", "", "name", atts);
                handler.characters(book.getName().toCharArray(), 0, book.getName().length());
                handler.endElement("", "", "name");
            }
            //创建author子节点
            if(book.getAuthor()!=null && !book.getAuthor().trim().equals("")){
                atts.clear();
                handler.startElement("", "", "author", atts);
                handler.characters(book.getAuthor().toCharArray(), 0, book.getAuthor().length());
                handler.endElement("", "", "author");               
            }
            //创建year子节点
            if(book.getYear()!=null && !book.getYear().trim().equals("")){
                atts.clear();
                handler.startElement("", "", "year", atts);
                handler.characters(book.getYear().toCharArray(), 0, book.getYear().length());
                handler.endElement("", "", "year");             
            }
            //创建price子节点
            if(book.getPrice()!=null && !book.getPrice().trim().equals("")){
                atts.clear();
                handler.startElement("", "", "price", atts);
                handler.characters(book.getPrice().toCharArray(), 0, book.getPrice().length());
                handler.endElement("", "", "price");                
            }
            //创建language子节点
            if(book.getLanguage()!=null && !book.getLanguage().trim().equals("")){
                handler.startElement("", "", "language", atts);
                handler.characters(book.getLanguage().toCharArray(), 0, book.getLanguage().length());
                handler.endElement("", "", "language");
            }           
            handler.endElement("", "", "book");             
        }
        handler.endElement("", "", "bookstore");
        //关闭document
        handler.endDocument();
    }
打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP