Tomcat相关技术-Digester(一)XML文件解析技术

2019-08-05  本文已影响0人  贪睡的企鹅

1 XML文件解析技术

Java解析XML文件有两个主要的实现方式:预加载DOM树事件机制的SAX

2 预加载DOM树

2.1 设计思想
2.2 具体实现
2.3 该思想有优点和缺点
2.4 案例

加载需要的jar包

<dependency>
      <groupId>org.dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>2.1.0</version>
    </dependency>

创建需要解析的xml

<books>
    <book author="天蚕土豆">
        <name>斗破苍穹</name>
        <price>86</price>
    </book>
    <book author="萧潜">
        <name>缥缈之旅</name>
        <price>92</price>
    </book>
    <book author="萧鼎">
        <name>诛仙</name>
        <price>98</price>
    </book>
    <book author="天下霸唱">
        <name>鬼吹灯</name>
        <price>124</price>
    </book>
    <book author="辰东">
        <name>神墓</name>
        <price>128</price>
    </book>
</books>

解析实例

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Dom4JTest {

    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        //document 加载执行xml文档获取Document对象
        Document document = saxReader.read(Dom4JTest.class.getResource("/books.xml"));
        //2.获取根元素的对象 -- books getRootElement 获取根元素
        Element rootElement = document.getRootElement();
        //每个元素的对象 都是Element对象
        List<Element> elements = rootElement.elements();
        //3.使用根元素的对象  对其他元素操作操作
        //3.1获取所有的子元素对象 book
        for (Element book : elements) {
            //在循环内拿到了 每个 book  元素对象
            //3.2获取book的属性值
            String author = book.attributeValue("author");
            //3.3获取book的子元素  name price
            String name = book.element("name").getText();
            String price = book.element("price").getText();
            System.out.println(name + " " + author + " " + price);
        }
    }
}

2 事件机制的SAX

2.1 设计思想
2.2 具体实现
2.3 该思想有优点和缺点
2.4 案例

创建需要解析的xml

<?xml version="1.0" encoding="UTF-8"?>
<PeopleList>
    <People id="1">
        <Name en='zhangsan'>张三</Name>
        <Age>20</Age>
    </People>
    <People id="2">
        <Name en='lisi'>李四</Name>
        <Age>30</Age>
    </People>
</PeopleList>

创建解析完成构建的model

public class People {
    private String id;
    private String name;
    private String englishName;
    private String age;
    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 getEnglishName() {
        return englishName;
    }
    public void setEnglishName(String englishName) {
        this.englishName = englishName;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }

}

创建解析器

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.List;

/**
 * 解析器需要继承DefaultHandler类
 */
public class SaxHandler extends DefaultHandler {

    //解析完成创建的model
    private List<People> peoples = null;
    //临时存储当前正在解析的People
    private People people;
    //临时存放挡墙解析的标签
    private String currentTag = null;
    //临时存放当前解析标签中字符  <>字符<>
    private String currentValue = null;
    //
    private String nodeName = null;

    public List<People> getPeoples() {
        return peoples;
    }

    public SaxHandler(String nodeName) {
        this.nodeName = nodeName;
    }

    /**
     * 触发解析一个xml文件开始事件时调用
     */
    @Override
    public void startDocument() throws SAXException {
        // TODO 当读到一个开始标签的时候,会触发这个方法
        super.startDocument();
        //初始化peoples
        peoples = new ArrayList<People>();
    }

    /**
     * 触发解析一个xml文件结束事件时调用
     */
    @Override
    public void endDocument() throws SAXException {
        // TODO 自动生成的方法存根
        super.endDocument();
    }

    /**
     * 触发解析一个xml标签开始事件时调用
     * @param uri
     * @param localName
     * @param name        当前标签的名称
     * @param attributes  标签中的属性
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String name,
                             Attributes attributes) throws SAXException {
        // TODO 当遇到文档的开头的时候,调用这个方法
        super.startElement(uri, localName, name, attributes);

        if (name.equals(nodeName)) {
            people = new People();
        }
        if (attributes != null && people != null) {
            for (int i = 0; i < attributes.getLength(); i++) {
                if(attributes.getQName(i).equals("id")){
                    people.setId(attributes.getValue(i));
                }
                else if(attributes.getQName(i).equals("en")){
                    people.setEnglishName(attributes.getValue(i));
                }
            }
        }
        currentTag = name;
    }


    /**
     * 触发解析一个xml标签结束事件时调用
     * @param uri
     * @param localName
     * @param name        当前标签的名称
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        // TODO 在遇到结束标签的时候,调用这个方法
        super.endElement(uri, localName, name);

        if (name.equals(nodeName)) {
            peoples.add(people);
        }
    }


    /**
     * 触发解析一个xml标签中字符调用(startElement触发之后endElement触发之前)
     * @param ch  xml文档完整字符
     * @param start   当前标签中字符在ch开始位置
     * @param length  当前标签中字符的长度
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO 这个方法用来处理在XML文件中读到的内容
        super.characters(ch, start, length);

        if (currentTag != null && people != null) {
            currentValue = new String(ch, start, length);
            if (currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("\n")) {
                if(currentTag.equals("Name")){
                    people.setName(currentValue);
                }
                else if(currentTag.equals("Age")){
                    people.setAge(currentValue);
                }
            }
        }
        currentTag = null;
        currentValue = null;
    }


}

测试代码

import java.util.List;

public class SaxTest {

    public static void main(String[] args) throws Exception {

        try {
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser parser = spf.newSAXParser();
            SaxHandler handler = new SaxHandler("People");
            parser.parse(Dom4JTest.class.getResource("/People.xml").openStream(), handler);

            List<People> peopleList = handler.getPeoples();
            for(People people : peopleList){
                System.out.println(people.getId()+"\t"+people.getName()+"\t"+people.getEnglishName()+"\t"+people.getAge());
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读