# 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
- 具有性能优异、灵活性好、功能强大和极端易用使用的特点
- 是一个开放源代码的软件