JAVA解析XML方式

Java解析XML文件共有四种方式:

1.DOM

2.SAX

3.DOM4j

4.JDOM

其中前两种方式是JAVA语言默认支持的,后两者为第三方jar包提供支持。

<!--样例文件book.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<bookList>
	<book id = "1">
		<name>冰与火之歌</name>
		<author>乔治马丁</author>
		<price>56</price>
	</book>
	<book id = "2">
		<name>Java编程思想</name>
		<author>SomeOne</author>
		<price>52</price>
	</book>
</bookList>
 

1.DOM解析,将整个文件解析后作为一个Document整体对象做处理。

/**
 * Created by Mr.Wang on 2019/2/20.
 */
public class DOMParseTest {
    public static void main(String[] args) {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();                           //1.获取DocumentBuilderFactory工厂对象
        try{
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();                              //2.创建DocumentBuilder对象
            Document document = documentBuilder.parse("I:\\practice\\book.xml");                                    //3.获取文件对象

            NodeList bookLists = document.getElementsByTagName("book");                                                 //根据节点名称获取子节点
            System.out.println("共有:" + bookLists.getLength() + "个book节点");
            for (int i = 0 ; i<bookLists.getLength() ; i++) {                                                           //遍历每一个节点
                Node book = bookLists.item(i);

                NamedNodeMap attrMap = book.getAttributes();                                                            //获取节点的属性
                System.out.println("节点" + i + "有" + attrMap.getLength() + "个属性");

                for (int j = 0; j < attrMap.getLength(); j++) {
                    Node attr = attrMap.item(j);
                    System.out.println("节点" + i + "的属性" + j + ":" + attr.getNodeName() + "--" + attr.getNodeValue());
                }

                NodeList childNodes = book.getChildNodes();                                                             //获取子节点
                System.out.println("节点" + i + "有" + childNodes.getLength() + "个子节点");
                for (int k = 0; k < childNodes.getLength() ; k++) {
                    Node child = childNodes.item(k);
                    if(child.getNodeType() == Node.ELEMENT_NODE){
                        String childNodeName =  child.getNodeName();                                                    //子节点名称
                        String childNodeValue = child.getTextContent();                                                 //节点内容
                        System.out.println("节点" + i + "的子节点" + k + ":" + childNodeName + "--" + childNodeValue);
                    }
                }

            }
        }catch(Exception e){
            System.out.println(e);
        }

    }
}

2.SAX解析,是遍历文件的同时,根据标签首/尾将标签内容解析出来。需要自定义ParseHandler类,重写方法。

其中常用的几个方法:

startDocument() , endDocument()  开始/结束 解析文档的方法

startElement() , endElement() 开始/结束 结束标签的方法

character() 获取标签值的方法

/**
 * Created by Mr.Wang on 2019/2/20.
 */
public class SAXParseTest {
    public static void main(String[] args){
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();                                             //1.获取SAXParserFactory工厂
        try{
            SAXParser saxParser = saxParserFactory.newSAXParser();                                                      //2.获取解析器
            SAXParseHandler handler = new SAXParseHandler();                                                            //3.创建自定义处理器对象    解析处理工作都在该对象中处理
            saxParser.parse("I:\\practice\\book.xml",handler);                                                      //4.解析文件
        }catch (Exception e){
            System.out.println(e);
        }

    }
}

class SAXParseHandler extends DefaultHandler{
    /**
     * 开始解析文件
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("开始解析文件...");
        super.startDocument();
    }

    /**
     * 解析文件结束
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("文件解析结束...");
    }

    /**
     * 开始解析元素
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);


        if(qName.equals("book")){
            System.out.println("==========开始遍历book节点========");
            System.out.println("book节点下共有" + attributes.getLength() + "个属性");
            for (int i = 0; i < attributes.getLength(); i++) {
                System.out.println("属性:" + i + ":" + attributes.getQName(i) + "-" + attributes.getValue(i));
            }
        }
        if(!qName.equals("book") && !qName.equals("bookList")){
            System.out.println("子节点:" + qName);
        }
    }

    /**
     * 结束解析元素
     * @param uri
     * @param localName
     * @param qName
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if(qName.equals("book")){
            System.out.println("==========结束遍历book节点========");
        }
    }

    /**
     * 获取节点值
     * @param ch
     * @param start
     * @param length
     * @throws SAXException
     */
    public void characters (char ch[], int start, int length) throws SAXException
    {
        super.characters(ch,start,length);
        String value = new String(ch, start, length);
        if(!"".equals(value.trim())){
            System.out.println(value);
        }

    }

}

3.JDOM 同DOM解析方式一样,将整个xml文件解析完后,针对Document这个对象进行处理。

package com.wang.com.XMLparse;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

/**
 * Created by Mr.Wang on 2019/2/26.
 */
public class JDOMParseDemo {
    public static void main(String[] args) {
        try {
            SAXBuilder saxBuilder = new SAXBuilder();                                                                   //1.创建SAXBuilder,需引入jdom2第三方jar包
            InputStream inputStream = new FileInputStream("I:\\practice\\book.xml");
            InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8"); //指定编码
            Document document = saxBuilder.build(reader);                                                               //2.获取Document对象   可根据文件直接创建,也可通过输入流创建

            Element rootElement = document.getRootElement();                                                            //获取根节点
            List<Element> childElements = rootElement.getChildren();                                                    //获取根节点的子节点
            for (Element child : childElements) {                                                                       //遍历子节点
                System.out.println("=====开始遍历book节点=====");
                List<Attribute> attributeList =  child.getAttributes();                                                 //获取属性列表
                for (int i = 0; i < attributeList.size(); i++) {
                    System.out.println("属性" + i + ":" + attributeList.get(i).getName() + "-" + attributeList.get(i).getValue());
                }
                List<Element> childNodes = child.getChildren();
                for (Element childNode : childNodes) {
                    System.out.println("节点" + childNode.getName() + ":" + childNode.getValue() );
                }
                System.out.println("=====结束遍历book节点=====");
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4.DOM4J解析XML文件也是将文件作为一个Document对象进行处理

package com.wang.com.XMLparse;

import com.sun.xml.internal.bind.v2.runtime.output.NamespaceContextImpl;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.Iterator;
import java.util.List;

/**
 * Created by Mr.Wang on 2019/2/26.
 */
public class DOM4JDemo {
    public static void main(String[] args) {
        try {
            SAXReader saxReader = new SAXReader();                                                                      //1.创建SAXReader对象
            Document document = saxReader.read("I:\\practice\\book.xml");                                      //2.获取Document对象

            Element rootElement = document.getRootElement();                                                            //获取根节点
            Iterator iterator = rootElement.elementIterator();                                                          //获取子节点的Iterator
            while(iterator.hasNext()){
                Element element = (Element) iterator.next();
                List<Attribute> attributes = element.attributes();                                                      //获取节点的属性
                for (Attribute attribute : attributes) {
                    System.out.println("属性" + attribute.getName() + ":" +attribute.getValue());
                }
                Iterator childIterator = element.elementIterator();
                while(childIterator.hasNext()){
                    Element childElement = (Element)childIterator.next();
                    System.out.println("子节点" + childElement.getName() + ":" +childElement.getText());
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

    }
}

 几种解析方式的优缺点比较:

1.DOM:

优点:1.形成整个文件的树形结构,便于理解与编程

           2.结构清楚,便于修改与保存

缺点:一次性将整个文件写入内存中,如果文件过大,会造成空间不足

2.SAX

优点:1.实时解析文件,不会造成内存浪费

缺点:结构不清晰,不便于理解与编程;很难同时处理多处相同标签

3.JDOM和DOM4J之间的比较:DOM4J在JDOM的基础上发展,效率更快。且相较于DOM方式,不会造成内存溢出。

推荐使用DOM4J

猜你喜欢

转载自blog.csdn.net/guaituo0129/article/details/87791412