sax解析

/**
* 这段代码的作用是对于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元素,如果想了解,可以自己上网查,也可以看我后续的博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值