Xml 文件解析的三种方式 Sax,Pull,Dom

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Stephen_mu/article/details/87071163

Dom: //将xml文件内容处理为树放在内存在解析,若xml文件大的话,比较消耗资源

Sax:  // 按照文本段落一行一行的读取文本内容,解析文件,tag头尾
         // 缺点: sax扫描完整个数据流才能开始处理

Pull:  // 类似于时间监听,对于元素,标签头尾解析过程存在事件监听,不同的事件对象不同的解析方式,
         // 且不需要像sax扫描完整个数据流才能开始处理
         // 和sax解析一样,基于流的方式进行处理,而不需要像dom解析那样,将xml文件内容处理为树放在内存在解析,若xml文件大的话,比较消耗资源

Dom解析例子:


public class DomParserHelper {
    
    private static Logger LOG = LoggerFactory.getLogger(XmlCreatorHelper.class);
    //将xml文件内容处理为树放在内存在解析,若xml文件大的话,比较消耗资源

    private static Map<String, String> map;
    private static List<Map<String, String>> list;

    private static DocumentBuilderFactory factory;
    private static DocumentBuilder builder;

    static {
        try {
            // 获取Dom解析器工程
            factory = DocumentBuilderFactory.newInstance();
            // 创建dom解析器
            builder = factory.newDocumentBuilder();
            list = new ArrayList<Map<String, String>>();
            map = new HashMap<String, String>();
        } catch (ParserConfigurationException e) {
            LOG.error("ParserConfigurationException", e);
        }
    }

    public List<Map<String, String>> parser(String filepath) {

        try {
            // 将需要解析的文档资源读入dom解析器
            Document document = builder.parse(new FileInputStream(new File(filepath)));

            // 直接获取某一节点下的所有节点列表
            NodeList rootlist = document.getElementsByTagName("person");

            // 遍历节点集合
            for (int i = 0; i < rootlist.getLength(); i++) {

                Element rootSon = (Element) rootlist.item(i);
                LOG.info(rootSon.getNodeName() + " ,i: " + i);
                map.put("id", rootSon.getAttribute("id"));

                // 获取person下面的所有子节点
                NodeList rootSonSonList = rootSon.getChildNodes();
                for (int j = 0; j < rootSonSonList.getLength(); j++) {
                    Node rootSonSon = rootSonSonList.item(j);

                    // 判断子node类型是否为元素Node
                    if (rootSonSon.getNodeType() == Node.ELEMENT_NODE) {

                        Element childElement = (Element) rootSonSon;

                        LOG.info("当前节点:  " , childElement.getNodeName());

                        if ("name".equals(childElement.getNodeName())) {
                            map.put("name", childElement.getTextContent());
                        }

                        if ("age".equals(childElement.getNodeName())) {
                            map.put("age", childElement.getTextContent());
                        }

                    }
                }
                list.add(map);
                map = new HashMap<String, String>();
            }
            return list;
        } catch (FileNotFoundException e) {
            LOG.error("FileNotFoundException", e);
        } catch (SAXException e) {
            LOG.error("SAXException", e);
        } catch (IOException e) {
            LOG.error("IOException", e);
        }
        return list;
    }

}

Sax解析例子:


public class SaxParserHelper extends DefaultHandler {

    private static Logger LOG = LoggerFactory.getLogger(SaxParserHelper.class);
    // 按照文本段落一行一行的读取文本内容,解析文件,tag头尾
    // 缺点: sax扫描完整个数据流才能开始处理

    private static Map<String, String> map;
    private List<Map<String, String>> list;
    private static SAXParser parser;
    // 当前解析的标签名
    private String tagName = "";

    static {
        try {
            // 得到解析器工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 创建Sax解析器
            parser = factory.newSAXParser();
        } catch (ParserConfigurationException e) {
            LOG.error("ParserConfigurationException", e);
        } catch (SAXException e) {
            LOG.error("SAXException", e);
        }

    }

    // 开始解析文档
    @Override
    public void startDocument() throws SAXException {
        map = new HashMap<String, String>();
        list = new ArrayList<Map<String, String>>();
        LOG.info("SAX: 开始解析文档");

    }

    /**
     * 开始解析元素,创建接受数据的实体
     * 
     * @param uri
     *            The Namespace URI, or the empty string if the element has no
     *            Namespace URI or if Namespace processing is not being performed.
     * @param localName
     *            标签名
     * @param qName
     *            The qualified name (with prefix), or the empty string if qualified
     *            names are not available.
     * @param attributes
     *            属性数组
     * 
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

        System.out.println("SAX: 开始解析" + "localName:" + localName + "--qName:" + qName);
        if (attributes.getValue(0) != null) {
            map.put(attributes.getQName(0), attributes.getValue(0));
        }
        this.tagName = qName;
        LOG.info("SAX: 开始解析头" + tagName + "元素");
    }

    /**
     * 读取数据,设置数据到实体
     * 
     * @param ch
     *            The characters.字符串内容
     * @param start
     *            The start position in the character array.
     * @param length
     *            The number of characters to use from the character array
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 判断当前标签是否有效
        if (tagName != null) {
            String value = new String(ch, start, length);
            if ((tagName == "name" || tagName == "age")) {
                map.put(tagName, value);
                LOG.info("SAX: 处理内容  " + tagName + "元素内容: " + value);
            }
        }
    }

    // 解析到元素尾时调用,注意是每一个元素尾都会调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        LOG.info("SAX: 开始解析" + "localName:" + localName + "--qName:" + qName);
        if (qName == "person") {
            list.add(map);
            map = new HashMap<String, String>();
        }

        this.tagName = null;
        LOG.info("SAX: 处理尾" + qName + "--" + tagName + "元素结束");
    }

    // 读取到文档尾时调用
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        LOG.info("SAX: 文档解析结束");
    }

    public List<Map<String, String>> parser(String filepathname) {
        try {
            File file = new File(filepathname);
            InputStream inputStream = new FileInputStream(file);
            parser.parse(inputStream, this);

            return list;
        } catch (SAXException e) {
            LOG.error("SAXException", e);
        } catch (IOException e) {
            LOG.error("IOException", e);
        }
        return null;
    }

}

Pull解析例子:
public class PullParserHelper {

    private static Logger LOG = LoggerFactory.getLogger(PullParserHelper.class);

    // 类似于时间监听,对于元素,标签头尾解析过程存在事件监听,不同的事件对象不同的解析方式,
    // 且不需要像sax扫描完整个数据流才能开始处理
    // 和sax解析一样,基于流的方式进行处理,而不需要像dom解析那样,将xml文件内容处理为树放在内存在解析,若xml文件大的话,比较消耗资源

    private static Map<String, String> map = null;
    private static List<Map<String, String>> list = null;

    private static XmlPullParserFactory factory;
    private static XmlPullParser parser;

    static {
        try {
            // 创建解析器工厂
            factory = XmlPullParserFactory.newInstance();
            // 获得解析器实体类
            parser = factory.newPullParser();

        } catch (XmlPullParserException e) {
            LOG.error("XmlPullParserException", e);
        }
    }

    public static List parser(String filepath) {

        try {
            // 获取解析文本的数据流
            InputStream inputStream = new FileInputStream(new File(filepath));
            parser.setInput(inputStream, "UTF-8");

            // 获取当前解析事件类型
            int eventType = parser.getEventType();
            while (eventType != parser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    map = new HashMap<String, String>();
                    break;
                case XmlPullParser.START_TAG:
                    if ("persons".equals(parser.getName())) {
                        list = new ArrayList<Map<String, String>>();
                    } else if ("person".equals(parser.getName())) {
                        map = new HashMap<String, String>();
                        if (map != null)
                            map.put("id", parser.getAttributeValue(null, "id"));
                    } else if ("name".equals(parser.getName())) {
                        // 获取该节点的内容
                        if (map != null)
                            map.put("name", parser.nextText());
                    } else if ("age".equals(parser.getName())) {
                        // 获取该节点的内容
                        if (map != null)
                            map.put("age", parser.nextText());
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if ("person".equals(parser.getName())) {
                        if (list != null) {
                            list.add(map);
                        }
                        if (map != null) {
                            map = null;
                        }
                    }
                    break;
                default:
                    break;
                }
                eventType = parser.next();
            }
            return list;

        } catch (FileNotFoundException e) {
            LOG.error("FileNotFoundException", e);
        } catch (XmlPullParserException e) {
            LOG.error("XmlPullParserException", e);
        } catch (IOException e) {
            LOG.error("IOException", e);
        }

        return list;
    }

}
 

猜你喜欢

转载自blog.csdn.net/Stephen_mu/article/details/87071163