XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。今天主要是介绍java中常用的四种解析XML的方法.
假设我们XML的内容和结构如下:
<?xml version="1.0" encoding="UTF-8"?> <HD> <disk name="C"> <capacity>4G</capacity> <directories>100</directories> <files>1580</files> </disk> <disk name="D"> <capacity>10G</capacity> <directories>300</directories> <files>1500</files> </disk> </HD>
用DOM来解析XML文件的操作比较简单,它的解析过程是先将XML文件读入内存,建立一棵文档树,通过对这颗文档树来操作来完成对XML文件的操作.
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU),且操作数据时要做大量的遍历树的操作,这对于大量数据的存取,修改操作率不高,但是对于小数据的一般性应用场合,用DOM来处理已经足够.
DOM解析:
package DOM; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class domXml { public static void main(String[] args) throws Exception{ //得到DOM解析器的工厂实例 DocumentBuilderFactory dbFactory=DocumentBuilderFactory.newInstance(); //从DOM工厂中获得DOM解析器 DocumentBuilder dbBuilder=dbFactory.newDocumentBuilder(); //声明为file为了识别中文名 Document document=null; document=dbBuilder.parse("D:/app/AnalysisXML/src/DOM/test.xml"); //得到文档名称为test的元素的节点列表 NodeList list =document.getElementsByTagName("disk"); //遍历该集合,显示结合中的元素及其子元素的名字 for(int i=0;i<list.getLength();i++) { Element element=(Element)list.item(i); String name=element.getAttribute("name"); String capacity=element.getElementsByTagName("capacity").item(0).getFirstChild().getNodeValue(); String directories=element.getElementsByTagName("directories").item(0).getFirstChild().getNodeValue(); String files=element.getElementsByTagName("files").item(0).getFirstChild().getNodeValue(); System.out.println("磁盘信息:"); System.out.println("分区盘符:"+name); System.out.println("分区容量:"+capacity); System.out.println("目录数:"+directories); System.out.println("文件数:"+files); System.out.println("-----------------------------------"); } } }
SAX是Simple API for XML的缩写,这并非官方标准,而是由网上社区讨论而产生的标准,几乎所有的XML解析器都会支持.SAX是指一种接口,或者一个软件包。也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式,用SAX解析XML文件,无须将文档读入内存.当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因此使用者所需要做的工作就是在相应的事件方法中加入程序代码.因而SAX接口也被称作事件驱动接口。
SAX解析:
test.java
package DOM; public class test { private String name; private String capacity; private String directories; private String files; public String Getname() { return name; } public void Setname(String name) { this.name=name; } public String Getcapacity() { return capacity; } public void Setcapacity(String capacity) { this.capacity=capacity; } public String Getdirectories() { return directories; } public void Setdirectories(String directories) { this.directories=directories; } public String Getfiles() { return files; } public void Setfiles(String files) { this.files=files; } }
package DOM; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import DOM.test; public class Saxxmltest { public static void main(String[] args) throws Exception { //解析器的获取 //1、获取sax解析工厂 SAXParserFactory sf = SAXParserFactory.newInstance(); //2、获取解析器 SAXParser sp = sf.newSAXParser(); //创建xml文件的输入流 InputStream inStream = SaxParseService.class.getClassLoader().getResourceAsStream("DOM/test.xml"); //3、解析xml文件,将事件处理器传入。 sp.parse(inStream, new Myhander()); } } class Myhander extends DefaultHandler{ private List<test> hd=null; private test disk=null; private String preTag =null; //作用是记录解析时的上一个节点名称 public void startDocument() throws SAXException { hd=new ArrayList<test>(); } public void startElement(String uriString,String localName,String qName,Attributes attributes) throws SAXException{ if("disk".equals(qName)){ disk=new test (); disk.Setname(attributes.getValue(0)); } preTag=qName; } public void characters(char[] ch,int start,int length)throws SAXException{ if(preTag!=null){ String contentString=new String(ch,start,length ); if("capacity".equals(preTag)){ disk.Setcapacity(contentString); } else if("directories".equals(preTag)){ disk.Setdirectories(contentString); }else if("files".equals(preTag)){ disk.Setfiles(contentString); } } } public void endElement(String uri,String localName,String qName) throws SAXException{ if("disk".equals(qName)){ hd.add(disk ); disk=null; } preTag=null; } public void endDocument() throws SAXException { for (test disk : hd) { System.out.println("磁盘信息:"); System.out.println("分区盘符:"+disk.Getname()); System.out.println("分区容量:"+disk.Getcapacity()); System.out.println("目录数:"+disk.Getdirectories()); System.out.println("文件数:"+disk.Getfiles()); System.out.println("-----------------------------------"); } } }
DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。dom4j的开发包中包含一些第三方开发包,当调用dom4j某些功能需要添加相应的开发包,大部分情况下,在项目中导入基本的dom4j.jar即可。
DOM4J解析:
package DOM; import java.util.Iterator; import org.apache.naming.java.javaURLContextFactory; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jXML { public static void main(String[] args) throws Exception{ //创建文件对象 java.io.File file=new java.io.File("D:/app/AnalysisXML/src/DOM/test.xml"); //创建一个读取XML文件的对象 SAXReader reader=new SAXReader(); //创建一个文档对象 Document document=reader.read(file); //获取文件的根节点 Element element=document.getRootElement(); for(Iterator i=element.elementIterator("disk");i.hasNext();){ //获取节点元素 element =(Element)i.next(); String name=element.attributeValue("name"); String capacity=element.elementText("capacity");//取disk子元素capacity的内容 String directories=element.elementText("directories"); String files=element.elementText("files"); System.out.println("磁盘信息:"); System.out.println("分区盘符:"+name); System.out.println("分区容量:"+capacity); System.out.println("目录数:"+directories); System.out.println("文件数:"+files); System.out.println("-----------------------------------"); } } }
jdom解析xml,是基于树型结构,其利用的是纯java技术,实现对xml文档的各种操作。jdom可以说是直接为java编程服务的,把sax与dom的功能有效的结合起来。JDOM应用程序的长度通常是DOM应用程序的三分之一,大约是SAX应用程序的一般.
优点:20-80原则,极大减少了代码量。
使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。
JDOM解析XML:
package DOM; import java.util.List; import javax.servlet.jsp.PageContext; import org.jdom.*; import org.jdom.input.*; public class JDomXML { public static void main (String[] args)throws Exception{ SAXBuilder sBuilder=new SAXBuilder(); Document document=sBuilder.build("src/DOM/test.xml"); //构造文档对象 Element rootElement=document.getRootElement();//获取根元素 List<Element> list=rootElement.getChildren("disk");//获取名字为disk的所有元素 for(int i=0;i<list.size();i++) //遍历根元素的子元素集合 { Element element=(Element)list.get(i); String name=element.getAttributeValue("name"); String capacity=element.getChildText("capacity");//取disk子元素capacity的内容 String directories=element.getChildText("directories"); String files=element.getChildText("files"); System.out.println("磁盘信息:"); System.out.println("分区盘符:"+name); System.out.println("分区容量:"+capacity); System.out.println("目录数:"+directories); System.out.println("文件数:"+files); System.out.println("-----------------------------------"); } } }
XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。XML的解析,可以更加自己的数据量的大小,选择不同的解析类型,同时提高解析效率!