Java 解析XML 4种方法总结

Java中用于解析XML的技术很多,主流的有DOM、SAX、JDOM、DOM4j,下文主要介绍这4种解析XML文档技术的使用。

//data_10k.xml
<?xml version="1.0" encoding="GB2312"?>  
<RESULT>  
<VALUE>     
  <NO>A1234</NO>     
  <ADDR>河南省郑州市</ADDR>  
</VALUE>  
<VALUE>     
  <NO>B1234</NO>     
  <ADDR>河南省郑州市二七区</ADDR>  
</VALUE>  
</RESULT>

DOM解析XML

org.w3c.dom由W3C提供的接口,它将整个XML文档读入内存,构建一个DOM树来对各个节点(Node)进行操作。它将XML看做是一颗树,DOM就是对这颗树的一个数据结构的描述,但对大型XML文件效果可能会不理想。更详细方法见Java XML解析 - 利用dom(org.w3c.dom)解析XML

public class MyXMLReader2DOM {
    public static void main(String arge[]) {
        long lasting = System.currentTimeMillis();
        try {
            File f = new File("data_10k.xml");
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(f);
            NodeList nl = doc.getElementsByTagName_r("VALUE");
            for (int i = 0; i < nl.getLength(); i++) {
                System.out.print("车牌号码:" + doc.getElementsByTagName_r("NO").item(i).getFirstChild().getNodeValue());
                System.out.println("车主地址:" + doc.getElementsByTagName_r("ADDR").item(i).getFirstChild().getNodeValue());
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

SAX解析XML

SAX不用将整个文档加载到内存,基于事件驱动的API(Observer模式),他按照xml文件的顺序一步一步的来解析,用户只需要注册自己感兴趣的事件即可。SAX提供EntityResolver, DTDHandler, ContentHandler, ErrorHandler接口,分别用于监听解析实体事件、DTD处理事件、正文处理事件和处理出错事件,与AWT类似,SAX还提供了一个对这4个接口默认的类DefaultHandler(这里的默认实现,其实就是一个空方法),一般只要继承DefaultHandler,重写自己感兴趣的事件即可。更详细方法见Java XML解析 - 利用SAX(Simple API for XML)解析XML

public class MyXMLReader2SAX extends DefaultHandler {
    java.util.Stack tags = new java.util.Stack();
    public MyXMLReader2SAX() {
        super();
    }
    public static void main(String args[]) {
        long lasting = System.currentTimeMillis();
        try {
            SAXParserFactory sf = SAXParserFactory.newInstance();
            SAXParser sp = sf.newSAXParser();
            MyXMLReader2SAX reader = new MyXMLReader2SAX();
            sp.parse(new InputSource("data_10k.xml"), reader);
        } catch(Exception e) {
            e.printStackTrace();
        }
        System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + "毫秒");
    }

    public void characters(char ch[], int start, int length) throws SAXException {
        String tag = (String) tags.peek();
        if (tag.equals("NO")) {
            System.out.print("车牌号码:" + new String(ch, start, length));
        }
        if (tag.equals("ADDR")) {
            System.out.println("地址:" + new String(ch, start, length));
        }
    }

    public void startElement(String uri, String localName, String qName, Attributes attrs) {
        tags.push(qName);
    }
}

JDOM解析XML

JDOM是一个开源项目,它基于树形结构,利用纯Java的技术对XML文档实现解析、生成、序列化及多种操作。JDOM与DOM非常类似,它是处理XML的纯JAVA API,API大量使用了Collections类,且JDOM仅使用具体类而不使用接口。JDOM 它自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档(尽管它还可以将以前构造的 DOM 表示作为输入)。更详细方法见Java XML解析 - 利用JDOM解析XML

public class MyXMLReader2JDOM {
    public static void main(String arge[]) {
        long lasting = System.currentTimeMillis();
        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(new File("data_10k.xml"));
            Element foo = doc.getRootElement();
            List allChildren = foo.getChildren();
            for (int i = 0; i < allChildren.size(); i++) {
                System.out.print("车牌号码:" + ((Element) allChildren.get(i)).getChild("NO").getText());
                System.out.println("车主地址:" + ((Element) allChildren.get(i)).getChild("ADDR").getText());
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

DOM4j解析XML

dom4j是一个简单的开源库,用于处理XML、 XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP。dom4j是目前在xml解析方面是最优秀的(Hibernate、Sun的JAXM也都使用dom4j来解析XML),它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。更详细方法见Java XML解析 - 利用DOM4j解析XML

public class MyXMLReader2DOM4J {
    public static void main(String arge[]) {
        long lasting = System.currentTimeMillis();
        try {
            File f = new File("data_10k.xml");
            SAXReader reader = new SAXReader();
            Document doc = reader.read(f);
            Element root = doc.getRootElement();
            Element foo;
            for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
                foo = (Element) i.next();
                System.out.print("车牌号码:" + foo.elementText("NO"));
                System.out.println("车主地址:" + foo.elementText("ADDR"));
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

DOM,SAX,JDOM,DOM4J四种方法对比总结

1. DOM是基于树的结构,通常需要加载整文档和构造DOM树,然后才能开始工作。
优点:
    a、由于整棵树在内存中,因此可以对xml文档随机访问
    b、可以对xml文档进行修改操作
    c、较sax,dom使用也更简单。
缺点:
    a、整个文档必须一次性解析完
    b、由于整个文档都需要载入内存,对于大文档成本高

2. SAX类似流媒体,它基于事件驱动的,因此无需将整个文档载入内存,使用者只需要监听自己感兴趣的事件即可。
优点:
    a、无需将整个xml文档载入内存,因此消耗内存少
    b、可以注册多个ContentHandler
缺点:
    a、不能随机的访问xml中的节点
    b、不能修改文档

3. JDOM是纯Java的处理XML的API,其API中大量使用Collections类,
优点:
    a、DOM方式的优点
    b、具有SAX的Java规则
缺点
    a、DOM方式的缺点

4. DOM4J是这4中xml解析方式中,最优秀的一个,集易用和性能于一身。

Java 解析XML推荐用DOM4J进行解析。