【Java】SAX解析xml文档总结

基本概念

什么是xml文件?

1.概念:
可扩展标记语言。作为数据的一种存储格式用于存储软件的参数。
2.xml和html的区别:

  • xml 重点:描述和存放数据。
  • html 重点:如何把数据更好的现实在页面上。

3.xml的标记分类:

  • 单标记<标记名称 />
  • 双标记<标记名称>…</标记名称>
    注意:如果标记内封装了其他字标记或内容,那么该标记一定是双标记。

4.标记的命名规则:

  • 标记名称必须以字母或下划线开头,后边包含字母、数字、下划线。

  • 标记名称必须严格区分大小写。

  • 标记必须顺序嵌套。

5.xml属性规则:

  • 属性名 = “属性值”。
  • 属性名必须以字母或下划线开头,后边可以有数字,字母、下划线;
  • 属性值必须括在引文的引号之内。
  • 属性名称必须唯一。

xml文件示例:

<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>webxml.LoginServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>reg</servlet-name>
        <servlet-class>webxml.RegisterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/g</url-pattern>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>reg</servlet-name>
        <url-pattern>/reg</url-pattern>
    </servlet-mapping>
</web-app>


SAX解析xml文档

什么是SAX解析?

SAX,全称Simple API for XML,是一种以事件驱动的XMl API,是XML解析的一种新的替代方法,解析XML常用的还有DOM解析,PULL解析(Android特有),SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点,对于Android等CPU资源宝贵的移动平台来说是一个巨大的优势。

SAX解析xml文件思路

(以上面示例中的webxml文件为例)
解析思路:
1.每遇到一个 < servlet >标签,可以根据该标签下对应的属性标签,将其加入到一个集合中。前提是要根据标签写好对应封装好的javabean,即可直接在容器中加入该对象。
2.由url-pattern(路径)—>(得到)Servlet-name(名称)—>Servlet-class(类名)。
需要用到的知识点:
1.java集合
2.java反射
3.java封装思想


SAX解析xml文件的步骤

  1. start Document(): -->解析文档开始
    具体:新建一个list,以便之后存储文档中的多个用户存储。
  2. start Element(): -->解析标签开始
    每遇到一个< servlet >或者< servlet-mapping> 标签,就要新建一个对应标签的对象。(前提是已经写好了对应的javabean)
  3. start character: -->解析标签及内容
    每个< servlet >或者< servlet-mapping> 标签下都有对应属性下的内容。每解析到对应属性,九江属性标签下的内容设置到当前对象的属性中。
  4. end Element(qname)
    每遇到< /servlet>或者< /servlet-mapping>时,便可以将当前对象加入到list中。
  5. 解析结束。

代码示例

1.解析代码:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.util.ArrayList;
import java.util.List;

public class WebXmlTest {
    public static void main(String[] args) throws Exception {
        SAXParserFactory factory1 = SAXParserFactory.newInstance();
        SAXParser parser1 = factory1.newSAXParser();
        //注册处理器
        webHandler handler = new webHandler();
        parser1.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("web.xml")
                ,handler);
        WebContext context = new WebContext(handler.getEntities(),handler.getMapings());
        //假设你输入了/login
        //这里用了反射奥
        String className = context.getClz("/reg");
        Class clz = Class.forName(className);
        System.out.println(className);

//        List<Entity> entities = handler.getEntities();
//        List<Maping> mapings = handler.getMapings();
//        System.out.println(entities.size());
//        System.out.println(mapings.size());
    }
}

class webHandler extends DefaultHandler{
    List<Entity> entities = new ArrayList<>();
    List<Maping> mapings = new ArrayList<>();
    Entity entity;
    Maping maping;
    String currentTag;
    private boolean isMapping = false;

    public webHandler() {

    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
       if(null!=qName){
           currentTag = qName;
           if(qName.equals("servlet")){
               entity = new Entity();
               isMapping = false;
           }else if(qName.equals("servlet-mapping")){
               maping = new Maping();
               isMapping = true;
           }
       }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        //System.out.println("!");
        if(null!=qName){
            if(qName.equals("servlet-mapping")){
                mapings.add(maping);
            }else if(qName.equals("servlet")){
                entities.add(entity);
            }
        }
        currentTag = null;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        String value = new String(ch, start, length).trim();
        if (null != currentTag) {
            if (!isMapping) {
                if (currentTag.equals("servlet-name")) {
                    entity.setName(value);
                } else if (currentTag.equals("servlet-class")) {
                    if(value.length()>0) {
                        entity.setClz(value);
                    }
                }
            } else {
                if (currentTag.equals("servlet-name")) {
                    maping.setName(value);
                } else if (currentTag.equals("url-pattern")) {
                        maping.addPattern(value);
                }
            }
        }
    }

    public List<Entity> getEntities() {
        return entities;
    }

    public List<Maping> getMapings() {
        return mapings;
    }
}

2.javabean代码:

public class Entity {
    private String name;
    private String clz;
    public Entity(String name, String clz) {
        this.name = name;
        this.clz = clz;
    }
    public Entity() {
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getClz() {
        return clz;
    }
    public void setClz(String clz) {
        this.clz = clz;
    }
}


public class Maping {
    private String name;
    private Set<String> patterns; //url-pattern中的元素不重复
    public Maping(String name, Set<String> patterns) {
        this.name = name;
        this.patterns = patterns;
    }
    public Maping(){
        patterns = new HashSet<String>();
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<String> getPatterns() {
        return patterns;
    }
    public void setPatterns(Set<String> patterns) {
        this.patterns = patterns;
    }
    public void addPattern(String pattern){
        this.patterns.add(pattern);
    }
}

注意:
解析时,每遇到一个endElement时都要将当前标签设置为空。
否则 < /servlet-name > ……(空) < servlet-class >之间的内容也会被解析。


利用反射处理webxml文件中的数据

基本过程

1.通过< servlet -mapping>中的URL(唯一)找到 Servlet-name。
2.通过name在Servlet中找到对应的class。

实现该过程要用到的方法

利用HashMap中键值对对应的方法。

代码
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WebContext {
    private List<Entity> entitys = null;
    private List<Maping> mapings = null;
    //key-->servlet-name value-->servlet-class
    private Map<String,String> entityMap = new HashMap<String,String>();
    //key-->url-pattern value-->servlet-name
    private Map<String,String> mappingMap = new HashMap<String,String>();

    public WebContext(List<Entity> entitys, List<Maping> mapings) {
        this.entitys = entitys;
        this.mapings = mapings;
    //将entity的list转成对应的map
        for(Entity entity:entitys){
            entityMap.put(entity.getName(),entity.getClz());
        }
    //将map的list转成对应的map
        for(Maping maping:mapings){
            for(String pattern:maping.getPatterns()){
                mappingMap.put(pattern,maping.getName());
            }
        }
    }
    /**
     * 通过URL的路径找到对应class
     * 1.通过url找到name
     * 2.通过name找到对应的class
     *
     */
    public String getClz(String pattern){
        String name = mappingMap.get(pattern);
        return entityMap.get(name);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值