DOM、JDOM、DOM4J解析XML
JAVA解析XML通常有两种方式,DOM和SAX(SAX前面已经示范)
DOM:Document Object Model(文档对象模型)
DOM的特性:
定义一组JAVA接口,基于对象,与语言和平台无关将XML文档表示为树,在内存中解析和存储XML文档,允许随机访问文档的不同部分
DOM解析XML
DOM的优点,由于树在内存中是持久的,因此可以修改后更新,它还可以在任何时候在树中上下导航,API使用起来也比较简单。
解析步骤:
DocumentBuilderFactory builder = DocumentBuilderFactory.newInstance();
DocumentBuilder db = builder.newDocumentBuilder();
db.parse(“person.xml”);
NodeList node_person = doc.getElementsByTagName(“person”);
XML文件:
<?xml version="1.0" encoding="UTF-8" ?> <people> <person personId="E01"> <name>Tony Blair</name> <address>10 Downing Street,London,UK</address> <tel>(061) 98765</tel> <fax>(061) 98765</fax> <email>qijingjing01@126.com</email> </person> <person personId="E02"> <name>Tony Blair</name> <address>10 Downing Street,London,UK</address> <tel>(061) 98765</tel> <fax>(061) 98765</fax> <email>qijingjing01@126.com</email> </person> </people>
进行解析
/** * DOM解析XML * 1.基于树形结构,通过解析器一次性把文档加载到内存中,所以会比较占用内存,可以随机访问 * 2.更加灵活,更适合在web开发者使用 */ @Test public void domParseXML() throws ParserConfigurationException, IOException, SAXException { //1. 创建一个DOM解析器工厂 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //2. 通过工厂对象创建生成解析器对象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //3. 解析文档 InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/lili/xmlAndJson/person.xml"); // 此代码完成后,整个XML文档已经被加载到内存中,以树状存储 Document doc = documentBuilder.parse(inputStream); //4. 从内存中读取数据 // 获取节点名称为person的所有节点,返回节点集合 NodeList personNodeList = doc.getElementsByTagName("person"); ArrayList<Person> person = new ArrayList<>(); Person p = null; for (int i = 0; i < personNodeList.getLength(); i++) { Node item = personNodeList.item(i); p = new Person(); String personId = item.getAttributes().getNamedItem("personId").getNodeValue(); p.setPersonId(personId); // 获取当前节点的所有子节点 NodeList childNodes = item.getChildNodes(); for (int i1 = 0; i1 < childNodes.getLength(); i1++) { Node item1 = childNodes.item(i1); String nodeName = item1.getNodeName(); if ("name".equals(nodeName)) { p.setName(item1.getFirstChild().getNodeValue()); } else if ("address".equals(nodeName)) { p.setAddress(item1.getFirstChild().getNodeValue()); } else if ("tel".equals(nodeName)) { p.setTel(item1.getFirstChild().getNodeValue()); } else if ("fax".equals(nodeName)) { p.setFax(item1.getFirstChild().getNodeValue()); } else if ("email".equals(nodeName)) { p.setEmail(item1.getFirstChild().getNodeValue()); } } person.add(p); } person.forEach(System.out::println); }
运行如下:
Person{personId='E01', name='Tony Blair', address='10 Downing Street,London,UK', tel='(061) 98765', fax='(061) 98765', email='qijingjing01@126.com'} Person{personId='E02', name='Tony Blair', address='10 Downing Street,London,UK', tel='(061) 98765', fax='(061) 98765', email='qijingjing01@126.com'}
JDOM解析XML:
JDOM是两位著名的java开发人员兼作者,Brett Mclaughlin 和 Jason Hunter的创作成果,2000年初在类似于Apache协议的许可下,JDOM作为一个开放源代码项目正式开始研发了。
JDOM简化了与XML的交互并且比使用DOM实现更快,JDOM与DOM主要有两方面不同,首先,JDOM仅使用具体类而不是接口,这在某些方面简化了API,但是也限制了灵活性,第二,API大量使用了Collections类,简化可那些已经熟悉这些类的java开发者的使用
Idea下载JDOMjar包,打开项目结构,点击+,
然后点击,箭头所示部分,
输入jdom,进行搜索
下载到合适的位置就可以了。
代码部分如下,运行结果同上
/** * 使用JDOM解析XML * 1.与DOM类似基于树形结构 * 2.与DOM的区别 * (1 第三方开源组件 * (2 实现使用java的Collection接口 * (3 效率比DOM更快 */ @Test public void jdomParseXML() throws IOException, JDOMException { // 创建JDOM解析器 SAXBuilder builder = new SAXBuilder(); InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/lili/xmlAndJson/person.xml"); org.jdom.Document build = builder.build(inputStream); // 获取根节点 Element rootElement = build.getRootElement(); List<Person> personList = new ArrayList<>(); Person person = null; List<Element> children = rootElement.getChildren(); for (Element element : children) { person = new Person(); String personId = element.getAttributeValue("personId"); person.setPersonId(personId); List<Element> children1 = element.getChildren(); for (Element element1 : children1) { String tag = element1.getName(); if ("name".equals(tag)) { person.setName(element1.getText()); } else if ("address".equals(tag)) { person.setAddress(element1.getText()); } else if ("tel".equals(tag)) { person.setTel(element1.getText()); } else if ("fax".equals(tag)) { person.setFax(element1.getText()); } else if ("email".equals(tag)) { person.setEmail(element1.getText()); } } personList.add(person); } personList.forEach(System.out::println); }
DOM4J解析XML:
dom4j是一个非常非常优秀的java XML API,具有性能优异。功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它,在对主流的java XML API进行的性能,功能和易用性的评测,dom4j无论在哪个方面都是非常出色的,如今你可以看到越来越多的java软件都在使用dom4j来读写XML,特别值得一提的练sun的JAXM也在用dom4j,这是必须使用的jar包,HIbernate用它来读写配置文件
下载jar包方式同上
代码如下:
/** * DOM4J解析XML * 基于树型结构,第三方组件 * 解析速度快,效率更高,使用JAVA中的迭代器实现数据读取,在web框架中使用较多(Hibernate) */ @Test public void dom4jParseXML() throws DocumentException { // 1.创建DOM4J的解析器对象 SAXReader reader = new SAXReader(); InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/lili/xmlAndJson/person.xml"); org.dom4j.Document doc = reader.read(inputStream); // 获取根节点 org.dom4j.Element rootElement = doc.getRootElement(); Iterator<org.dom4j.Element> iterator = rootElement.elementIterator(); ArrayList<Person> personList = new ArrayList<>();Person p = null; while (iterator.hasNext()){ p = new Person(); org.dom4j.Element e = iterator.next(); p.setPersonId(e.attributeValue("personId")); Iterator<org.dom4j.Element> iterator1 = e.elementIterator(); while(iterator1.hasNext()){ org.dom4j.Element next = iterator1.next(); String tag = next.getName(); if ("name".equals(tag)) { p.setName(next.getText()); } else if ("address".equals(tag)) { p.setAddress(next.getText()); } else if ("tel".equals(tag)) { p.setTel(next.getText()); } else if ("fax".equals(tag)) { p.setFax(next.getText()); } else if ("email".equals(tag)) { p.setEmail(next.getText()); } } personList.add(p); } personList.forEach(System.out::println); }
运行结果同上。
各种解析方法比较:
JDOM和DOM在性能测试时表现不佳,在测试10M文档时会内存溢出
SAX表现较好,这要依赖于它特定的解析方式,一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)
DOM4J是这场测试的获胜者,目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也是DOM4J来读取XML配置文件