# parseXML **Repository Path**: awgsyfy/parse-xml ## Basic Information - **Project Name**: parseXML - **Description**: Java解析XML文件的4种方法 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2020-12-29 - **Last Updated**: 2021-10-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java解析XML文件的4种方法 > 参考: https://blog.csdn.net/m0_37499059/article/details/80505567 # 一、解析示例文件 `example.xml` ```xml cxx1 Bob1 stars1 85 cxx2 Bob2 stars2 85 cxx3 Bob3 stars3 85 ``` # 二、DOM方式解析 - `pom.xml` ```xml 4.0.0 top.syfy.xml parse-xml 1.0-SNAPSHOT top.syfy.xml parse-by-dom 1.0-SNAPSHOT parse-by-dom DOM方式解析XML文件 UTF-8 UTF-8 1.8 1.8 1.8 org.w3c dom 2.3.0-jaxb-1.0.6 ``` - `ParseByDom.java` ```java package top.syfy.xml; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.File; import java.io.IOException; /** * DOM方式解析XML文件 * */ public class ParseByDom { /** * 使用Node的方式 * @param nodes 节点列表 */ public static void node(NodeList nodes) { for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); NodeList childNodes = node.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node childNode = childNodes.item(j); if (Node.ELEMENT_NODE == childNode.getNodeType()) { // 获取节点 System.out.print(childNode.getNodeName() + " : "); // 获取节点值 System.out.println(childNode.getFirstChild().getNodeValue()); } } } } public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException { // 创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new File("example.xml")); NodeList studentList = document.getElementsByTagName("student"); node(studentList); } } ``` - 结果 ``` firstname : cxx1 lastname : Bob1 nickname : stars1 marks : 85 firstname : cxx2 lastname : Bob2 nickname : stars2 marks : 85 firstname : cxx3 lastname : Bob3 nickname : stars3 marks : 85 ``` # 三、SAX方式解析 - `pom.xml` ```xml 4.0.0 top.syfy.xml parse-xml 1.0-SNAPSHOT top.syfy.xml parse-by-sax 1.0-SNAPSHOT parse-by-sax SAX方式解析XML文件 UTF-8 UTF-8 1.8 1.8 1.8 ``` - `ParseBySax.java` ```java package top.syfy.xml; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.File; import java.io.IOException; /** * SAX方式解析XML文件 */ public class ParseBySax { public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException { // 获取SaxParserFactory实例 SAXParserFactory factory = SAXParserFactory.newInstance(); // 获取SAXParser实例 SAXParser saxParser = factory.newSAXParser(); // 创建SAXHandler对象 SAXHandler handler = new SAXHandler(); saxParser.parse(new File("example.xml"), handler); } } /** * sax解析是从上到下依次解析, 如example.xml中的class -> student -> student -> ... */ class SAXHandler extends DefaultHandler { /** * 节点属性的索引 */ static int attributeIndex = 0; /** * XML文档遍历开始时的操作 */ @Override public void startDocument() throws SAXException { super.startDocument(); System.out.println("=====sax文档解析开始=====\n\n"); } /** * XML文档遍历结束时的操作 */ @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("\n\n=====sax文档解析结束====="); } /** * 每个节点遍历开始时的操作 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if ("student".equals(qName)) { System.out.println("=====开始遍历student节点====="); /* 遍历获取节点属性名称和属性值 获取属性名称: getLocalName(int index) ==> 其中index为节点属性名称的索引值(从0开始) 获取属性值: getValue(String attributeName) ==> 其中attributeName为节点属性名称 */ String attributeName; while ((attributeName = attributes.getLocalName(attributeIndex++)) != null) { System.out.println("属性: " + attributeName + "=" + attributes.getValue(attributeName)); } } else if (!"class".equals(qName)) { System.out.print("节点名称: " + qName + "="); } } /** * 每个节点遍历结束时的操作 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if ("student".equals(qName)) { System.out.println("=====结束遍历student节点====="); attributeIndex = 0; } } /** * 返回的是节点的值 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); String value = new String(ch, start, length).trim(); if (!"".equals(value)) { System.out.println(value); } } } ``` - 结果 ``` =====sax文档解析开始===== =====开始遍历student节点===== 节点名称: firstname=cxx1 节点名称: lastname=Bob1 节点名称: nickname=stars1 节点名称: marks=85 =====结束遍历student节点===== =====开始遍历student节点===== 属性: no=493 节点名称: firstname=cxx2 节点名称: lastname=Bob2 节点名称: nickname=stars2 节点名称: marks=85 =====结束遍历student节点===== =====开始遍历student节点===== 属性: no=593 属性: status=1 节点名称: firstname=cxx3 节点名称: lastname=Bob3 节点名称: nickname=stars3 节点名称: marks=85 =====结束遍历student节点===== =====sax文档解析结束===== ``` # 四、JDOM方式解析 - `pom.xml` ```xml 4.0.0 top.syfy.xml parse-xml 1.0-SNAPSHOT top.syfy.xml parse-by-jdom 1.0-SNAPSHOT parse-by-jdom JDOM方式解析XML文件 UTF-8 UTF-8 1.8 1.8 1.8 org.jdom jdom 2.0.2 ``` - `ParseByJdom.java` ```java package top.syfy.xml; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * * JDOM方式解析XML文件 */ public class ParseByJdom { public static void main( String[] args ) throws IOException, JDOMException { // 创建SAXBuilder对象 SAXBuilder builder = new SAXBuilder(); // 创建输入流 InputStream in = new FileInputStream(new File("example.xml")); // 将输入流加载到SAXBuilder中 Document document = builder.build(in); // 获取根节点 Element rootElement = document.getRootElement(); // 获取子节点student List studentElementList = rootElement.getChildren(); for (Element stuEle:studentElementList) { // 遍历student节点的属性 List attributeList = stuEle.getAttributes(); for (Attribute attribute:attributeList) { System.out.println("属性: " + attribute.getName() + "=" + attribute.getValue()); } // 遍历student节点的子节点 List studentSubElementList = stuEle.getChildren(); for (Element sub:studentSubElementList) { System.out.println("节点: " + sub.getName() + "=" + sub.getValue()); } } } } ``` - 结果 ``` 节点: firstname=cxx1 节点: lastname=Bob1 节点: nickname=stars1 节点: marks=85 ========================= 属性: no=493 节点: firstname=cxx2 节点: lastname=Bob2 节点: nickname=stars2 节点: marks=85 ========================= 属性: no=593 属性: status=1 节点: firstname=cxx3 节点: lastname=Bob3 节点: nickname=stars3 节点: marks=85 ========================= ``` # 五、DOM4J方式解析 - `pom.xml` ```xml 4.0.0 top.syfy.xml parse-xml 1.0-SNAPSHOT top.syfy.xml parse-by-dom4j 1.0-SNAPSHOT parse-by-dom4j DOM4J方式解析XML文件 UTF-8 UTF-8 1.8 1.8 1.8 org.dom4j dom4j 2.1.3 ``` - `ParseByDom4j.java` ```java package top.syfy.xml; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.File; import java.util.Iterator; import java.util.List; /** * DOM4j方式解析XML文件 * */ public class ParseByDom4j { public static void main( String[] args ) throws DocumentException { // 创建Reader对象 SAXReader reader = new SAXReader(); // 创建输入流 InputStream in = new FileInputStream(new File("example.xml")); // 加载XML文件 Document document = reader.read(in); // 获取根节点 Element rootElement = document.getRootElement(); // 遍历节点 Iterator iterator = rootElement.elementIterator();; while (iterator.hasNext()) { // 获取student节点 Element studentElement = iterator.next(); // 遍历student节点的属性 List attributeList = studentElement.attributes();; for (Attribute attribute:attributeList) { System.out.println("属性: " + attribute.getName() + "=" + attribute.getValue()); } // 获取student节点的子节点 List studentSubElementList = studentElement.elements();; // 遍历student节点的子节点 for (Element sub:studentSubElementList) { System.out.println("节点: " + sub.getName() + "=" + sub.getStringValue()); } System.out.println("========================="); } } } ``` - 结果 ``` 节点: firstname=cxx1 节点: lastname=Bob1 节点: nickname=stars1 节点: marks=85 ========================= 属性: no=493 节点: firstname=cxx2 节点: lastname=Bob2 节点: nickname=stars2 节点: marks=85 ========================= 属性: no=593 属性: status=1 节点: firstname=cxx3 节点: lastname=Bob3 节点: nickname=stars3 节点: marks=85 ========================= ``` # 六、DOM-SAX-JDOM-DOM4J的比较 - DOM - 优点 - 形成了树结构,直观好理解,代码更易编写 - 解析过程中树结构保留在内存中,方便修改 - 缺点 - 当xml文件较大时,对内存耗费比较大,容易影响解析性能并造成内存溢出 - SAX - 优点 - 采用事件驱动模式,对内存耗费比较小 - 适用于只需要处理xm中数据时 - 缺点 - 不易编码 - 很难同时访问同一个xml中的多处不同数据 - JDOM - 仅使用具体类而不使用接口 - API大量使用了Collections类 - DOM4J - JDOM的一种智能分支,它合井了许多超出基本XML文档表示的功能 - DOM4J使用接口和抽象基本类方法,是一个优秀的 Java XML API - 具有性能优异、灵活性好、功能强大和极端易用使用的特点 - 是一个开放源代码的软件