利用三种方式解析如下的xml
jar name func1 XXX转换函数 234353928349323 from Param from value to Param to value
1、DOM(JAXP Crimson解析器)
-
1、介绍
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。jdk已经内置,不需要任何maven依赖,但是用起来非常难用
-
2、代码
import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; /** * 使用DOM来解析xml * jdk内置的,不需要依赖第三方jar * 最难用 * * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2018/9/30 9:26 */ public class DomDemo { public static void main(String[] args) { try { DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance(); DocumentBuilder domBuilder = domfac.newDocumentBuilder(); //Document doc = domBuilder.parse(new File("E:\\transfun.xml")); Document doc = domBuilder.parse("E:\\transfun.xml"); //获取到最外层的文档结构,最外层xml随意定,不一定要叫
Element root = doc.getDocumentElement(); NodeList project = root.getElementsByTagName("project"); int length = project.getLength(); // 1,因为具体获取,所以为1 for (int i = 0; i < length; i++) { Node item = project.item(i); /** * 获取里面的所有子节点,包括属性和params * 但是注意:childLength不是5,而是11,这是dom的问题,每一行的后面有一个\n也会被当做一个节点 * 也就是project、name、transFunc、desc、id、params都会有一个\n,所以是11个 * 因此需要判断nodeName才能知道是那个节点 * 另外,最终取数据的时候还要.getFirstChild() */ NodeList childNodes = item.getChildNodes(); int childLength = childNodes.getLength(); for (int j = 0; j < childLength; j++) { Node temp = childNodes.item(j); if (temp.getNodeType() != Node.ELEMENT_NODE) { // \n 的情况 continue; } if ("name".equals(temp.getNodeName())) { System.out.println("name:" + temp.getFirstChild().getNodeValue()); } else if ("transFunc".equals(temp.getNodeName())) { System.out.println("transFunc:" + temp.getFirstChild().getNodeValue()); } else if ("desc".equals(temp.getNodeName())) { System.out.println("desc:" + temp.getFirstChild().getNodeValue()); } else if ("id".equals(temp.getNodeName())) { System.out.println("id:" + temp.getFirstChild().getNodeValue()); } else if ("params".equals(temp.getNodeName())) { // 重新构建一个params的domcument文档,当然也可以继续使用getChildNodes,但是要进行\n过滤判断 Document ownerDocument = temp.getOwnerDocument(); NodeList params = ownerDocument.getElementsByTagName("param"); int paramLength = params.getLength(); for (int k = 0; k < paramLength; k++) { Node item1 = params.item(k); NodeList nodes = item1.getChildNodes(); int paramChildLength = nodes.getLength(); for (int l = 0; l < paramChildLength; l++){ Node item2 = nodes.item(l); if (item2.getNodeType() != Node.ELEMENT_NODE) { // \n 的情况 continue; } if ("name".equals(item2.getNodeName())) { System.out.println("param name:" + item2.getFirstChild().getNodeValue()); } else if ("value".equals(item2.getNodeName())) { System.out.println("param value:" + item2.getFirstChild().getNodeValue()); } } } } } } } catch (Exception e) { e.printStackTrace(); } } }
2、JDOM
-
1、介绍
JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。是在Apache许可证变体下发布的开放源码。
-
2、maven依赖
org.jdom jdom 1.1.3 -
3、代码
import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import java.util.List; /** * JDome解析xml,比jdk自带的dom好用多了 * 几乎只需要getChild和getChildren即可 * * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2018/9/30 11:48 */ public class JDomeDemo { public static void main(String[] args) { try { // 构建文档 SAXBuilder builder = new SAXBuilder(); //Document doc = builder.build(new File("E:\\transfun.xml")); Document doc = builder.build("E:\\transfun.xml"); // 解析文档 Element root = doc.getRootElement(); Element project = root.getChild("project"); //获取project最外层的属性 Element nameElement = project.getChild("name"); System.out.println("name: " + nameElement.getValue()); Element transFunc = project.getChild("transFunc"); System.out.println("transFunc: " + transFunc.getValue()); Element desc = project.getChild("desc"); System.out.println("desc: " + desc.getValue()); Element id = project.getChild("id"); System.out.println("id: " + id.getValue()); Element params = project.getChild("params"); List
paramList = params.getChildren("param"); for (Element temp : paramList) { Element name = temp.getChild("name"); System.out.println("param name: " + name.getValue()); Element value = temp.getChild("value"); System.out.println("param value: " + value.getValue()); } } catch (Exception e) { e.printStackTrace(); } } }
3、DOM4J
-
1、介绍
虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。
为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。 在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。
DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J。
-
2、maven依赖
org.dom4j dom4j 2.0.0 -
3、代码
import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; import java.util.List; /** * Dom4j解析xml,性能最好,最灵活 * 能够嵌套层次查询project/params/param,也能够直接查询name * * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2018/9/29 17:57 */ public class Dom4jDemo { public static void main(String[] args) { try { SAXReader reader = new SAXReader(); // Document document = reader.read(new File("E:\\transfun.xml")); Document document = reader.read("E:\\transfun.xml"); //获取到最外层的文档结构,最外层xml随意定,不一定要叫
Element root = document.getRootElement(); Node name = root.selectSingleNode("project/name"); System.out.println("name:" + name.getStringValue()); Node funcName = root.selectSingleNode("project/transFunc"); System.out.println("name:" + funcName.getStringValue()); Node funcDesc = root.selectSingleNode("project/desc"); System.out.println("funcDesc:" + funcDesc.getStringValue()); Node id = root.selectSingleNode("project/id"); System.out.println("id:" + id.getStringValue()); List paramsNode = root.selectNodes("project/params/param"); for (Node node : paramsNode) { Node paramName = node.selectSingleNode("name"); System.out.println("param name:" + paramName.getStringValue()); Node value = node.selectSingleNode("value"); System.out.println("param value:" + value.getStringValue()); } } catch (Exception ignored) { } } }
2、比较和总结
-
1、DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
-
2、JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM。虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
-
3、SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。