XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。
XML的解析方式分为四种:1、DOM解析;2、SAX解析;3、JDOM解析;4、DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。
我们针对以下XML文件,做出四种解析
<?xml version="1.0" encoding="UTF-8" ?> <Note> <user id="0"> <username>user1</username> <password>pad1</password> </user> <user id="1"> <username>user2</username> <password>pad2</password> </user> <user id="2"> <username>user3</username> <password>pad3</password> </user> <user id="3"> <username>user4</username> <password>pad4</password> </user> <user id="4"> <username>user5</username> <password>pad5</password> </user> </Note>
第一中解析方式,DMO解析
DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。
优点:
形成了树结构,有助于更好的理解、掌握,且代码容易编写,解析过程中,树结构保存在内存中,方便修改。
缺点:
由于文件是一次性读取,所以文件如果过大,容易影响解析性能且可能会造成内存溢出。
DMO解析代码
1 public class DOMDemo { 2 public static void main(String[] args) throws Exception { 3 //创建解析器工厂 4 DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); 5 //创建解析器 6 DocumentBuilder db =dbf.newDocumentBuilder(); 7 //创建文件 8 File file=new File("../breeze_xml/test.xml"); 9 //解析xml文件,获得一个文件树 10 Document document=db.parse(file); 11 //找到树的子节点元素 12 Element ele= document.getDocumentElement(); 13 //一个xml文件只有一个根节点,获得根节点下的所有子节点,返回一个集合 14 System.out.println("显示所有节点"); 15 showElement(ele); 16 System.out.println("\n显示所有元素"); 17 show(ele); 18 } 19 20 /* 21 * 显示节点和文本 22 */ 23 private static void showElement(Element ele) { 24 NodeList nodelist= ele.getChildNodes(); 25 for (int i = 0; i < nodelist.getLength(); i++) { 26 Node childNode=nodelist.item(i);//依次得到每一个子节点 27 //因为我们要操作的是元素(Element)而不是节点(Node),所以转换成元素 28 //因为我们知道Element是Node的字类,所以判断每个节点是否属于Node 29 if(childNode instanceof Element) { 30 //父类转字类,因为要用子类的方法 31 Element chileEle=(Element)childNode; 32 //判断是否还有子节点,递归遍历 33 if(chileEle.hasChildNodes()) { 34 System.out.println(chileEle.getNodeName()); 35 showElement(chileEle); 36 } 37 } 38 } 39 } 40 /* 41 * 显示节点 42 */ 43 private static void show(Element ele) { 44 NodeList nodelist= ele.getChildNodes(); 45 for (int i = 0; i < nodelist.getLength(); i++) { 46 //通过item方法,获取一个子节点,现在获得是5个user 47 Node child=nodelist.item(i); 48 //判断子节点是否是Elemet的字类,是的话就给个父类类型 49 if(child instanceof Element) { 50 Element childElement=(Element)child; 51 //输入根节点下子节点的名字 52 //判断元素是否有属性 53 if(childElement.hasAttribute("id")) { 54 //输出当前节点的标签名字 55 System.out.println(childElement.getTagName()); 56 //递归当前方法,子标签如果没有属性 57 show(childElement); 58 }else { 59 //则输出自标签的标签名字+文本 60 System.out.println("\t"+childElement.getTagName()+"\t"+childElement.getTextContent()); 61 } 62 } 63 } 64 System.out.println(); 65 } 66 }