sax解析

来源:互联网 发布:淘宝旧版本5.7.0下载 编辑:程序博客网 时间:2024/06/03 12:30

/**
* 这段代码的作用是对于xml的增删该改查,使用的sax解析的方式
*sax和stax解析技术都是基于事件驱动的用到的类为DefaultHandler
*sax常用时间
*startDocument();–文档开始事件
*startElement();—–元素开始事件
*characters();——-文本事件
*endElement();——–元素结束事件
*EndDocument;———文档结束事件
*/
首先我们创建xml文件,具体代码如下

<?xml version="1.0" encoding="UTF-8" standalone="no"?><books>  <book>        <name> 高效java </name>        <pirce>50 </pirce>    </book>    <book>        <name>  java编程思想  </name>            <pirce> 80  </pirce>    </book></boos>
/** *  */package com.effective_java;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;/** * @author 干枯的骆驼 了解基本的sax解析技术 */public class Model7 {    /**     * @param args     * @throws SAXException     * @throws ParserConfigurationException     */    public static void main(String[] args) throws Exception {        // TODO 自动生成的方法存根        myhandleter myhandleter = new myhandleter();        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();// 创建sax解析工厂        SAXParser saxParser = saxParserFactory.newSAXParser();// 通过解析工厂得到解析对象        saxParser.parse("text1.xml", myhandleter);// 传递的参数为xml文件和defaultHandler的实现类,所以我们要创建继承一个了defaulthandlter的类        // 通过解析对象解析xml    }}class myhandleter extends DefaultHandler {    @Override    public void startDocument() throws SAXException {        // TODO 自动生成的方法存根        super.startDocument();        System.out.println("stratDocument");    }    @Override    public void endDocument() throws SAXException {        // TODO 自动生成的方法存根        super.endDocument();        System.out.println("EndDocument");    }    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        // TODO 自动生成的方法存根        super.startElement(uri, localName, qName, attributes);        System.out.println("StratElement");    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        // TODO 自动生成的方法存根        super.endElement(uri, localName, qName);        System.out.println("EndElement");    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        // TODO 自动生成的方法存根        super.characters(ch, start, length);        System.out.println("characters");    }}

下面我们来修改信息,获得所有的值

    class MyDefaultHeader extends DefaultHandler{/* * SAX2 事件处理程序的默认基类。 * 这里方法实在是多,我们就使用其中常用的属性进行重写 *就这几个,大家可能不是特别理解这是什么意思 *大家可以这样理解 *一个DefaultHandler就是一个节点,也就是一个标签 *那么这里就非常好理解了 *startDocument代表文档开始 *endDocument代表的是文档结束 *character代表节点的数据,节点的信息都存在这里 *startElement代表的是文档内的节点开始 *EndElement 代表的是文档内的结束 *  * * */        String nodename;       StringBuilder name;       StringBuilder pirce;    @Override    public void startDocument() throws SAXException {//      System.out.println("文档开始了");        name=new StringBuilder();        pirce=new StringBuilder();    }      @Override        public void endDocument() throws SAXException {//     System.out.println("文档结束了");        }   @Override        public void characters(char[] arg0, int arg1, int arg2)                throws SAXException {            //System.out.println("节点的内容");           if(nodename.equals("name")){             name.append(arg0,arg1,arg2);           }else if(nodename.equals("pirce")){               pirce.append(arg0,arg1,arg2);        }   }   /*    * uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。     localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。     qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。      attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。    */   @Override        public void startElement(String uri, String localName, String qName,                Attributes attributes) throws SAXException {           nodename=qName;   }   /** uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。 localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。 qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。     */    @Override            public void endElement(String uri, String localname, String qname)                    throws SAXException {        //System.out.println("元素结束");        if("book".equals(qname)){            System.out.println(name.toString().trim());            System.out.println(pirce.toString().trim());/*在这里你必须使用trim()函数解决空格问题因为产生的空格会造成判断错误,举个例子,请看下面例子*/            name.setLength(0);            pirce.setLength(0);        }        }       }

结果如下这里写图片描述

看下面例子我做查询检索数据
其他都一样,我们修改endElement方法
查询pirce>60的书的信息

            public void endElement(String uri, String localname, String qname)                    throws SAXException {        //System.out.println("元素结束");        if("book".equals(qname)){            if(Integer.parseInt(pirce.toString())>60){            System.out.println(name.toString());            System.out.println(pirce.toString());            name.setLength(0);            pirce.setLength(0);            }        }

结果真的哭了
这里写图片描述

傻逼的我还以为自己智商有问题
结果发现就是自己智商有问题
加上trim();方法

然后我又继续尝试

        public void endElement(String uri, String localname, String qname)                    throws SAXException {        //System.out.println("元素结束");        if("book".equals(qname)){            if(Integer.parseInt(pirce.toString().trim())>60){            System.out.println(name.toString());            System.out.println(pirce.toString());            name.setLength(0);            pirce.setLength(0);            }        }

TMD结果还是这样
结果这下真的哭了
这里写图片描述
然后我继续排查
代码修改如下,我用了一个方法封装了打印的操作

    @Override            public void endElement(String uri, String localname, String qname)                    throws SAXException {        //System.out.println("元素结束");        if("book".equals(qname)){            System.out.print(Integer.parseInt(pirce.toString().trim())>=60?print(name, pirce):false);            name.setLength(0);            pirce.setLength(0);        }        }       }    private boolean print(StringBuilder name,StringBuilder pirce){        System.out.println(name.toString().trim());        System.out.println(pirce.toString().trim());        return true;    }

用到了三目运算符,具体的原因我还不太清楚,我当时猜是因为换行
当也不太确定,知道答案的请回复我,谢谢

我就说到这了,具体的大家自己查看api就知道了,大致来说上面就是一个模板,我们通过对endElement()方法的操作,就能达到数据检索的作用,在开发中,往往会对xml解析,获得对应的值,就相当于一个数据库一样,当然对应的还有序列化,将数据集合序列化为xml元素,如果想了解,可以自己上网查,也可以看我后续的博客