XML常用解析方式

在Java中解析XML文件有多种方式,每种方式都有其适用场景和特点。常见的XML解析方式包括:

  1. DOM(Document Object Model)解析
  2. SAX(Simple API for XML)解析
  3. StAX(Streaming API for XML)解析
  4. JAXB(Java Architecture for XML Binding)解析
  5. 第三方库(如 Jsoup 和 JDOM)

下面是对每种方式的详细介绍和示例代码。

1. DOM解析

DOM(Document Object Model)解析是将整个XML文档加载到内存中,解析后形成一个树形结构,便于随机访问和操作。

适用场景

  • XML文档较小。
  • 需要对文档进行多次遍历或修改。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class DOMParserExample {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("example.xml");

Element root = document.getDocumentElement();
System.out.println("Root element: " + root.getTagName());

NodeList nodeList = root.getElementsByTagName("employee");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
System.out.println("Employee ID: " + element.getAttribute("id"));
System.out.println("Name: " + element.getElementsByTagName("name").item(0).getTextContent());
System.out.println("Age: " + element.getElementsByTagName("age").item(0).getTextContent());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

2. SAX解析

SAX(Simple API for XML)解析是一种事件驱动的解析方式,它逐行读取XML文件,遇到不同的事件(如开始标签、结束标签等)时调用相应的处理方法。

适用场景

  • 处理大型XML文件。
  • 需要快速读取XML文件。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserExample {
public static void main(String[] args) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();

DefaultHandler handler = new DefaultHandler() {
boolean bName = false;
boolean bAge = false;

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("employee")) {
String id = attributes.getValue("id");
System.out.println("Employee ID: " + id);
} else if (qName.equalsIgnoreCase("name")) {
bName = true;
} else if (qName.equalsIgnoreCase("age")) {
bAge = true;
}
}

public void characters(char ch[], int start, int length) throws SAXException {
if (bName) {
System.out.println("Name: " + new String(ch, start, length));
bName = false;
} else if (bAge) {
System.out.println("Age: " + new String(ch, start, length));
bAge = false;
}
}
};

saxParser.parse("example.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
}
}

3. StAX解析

StAX(Streaming API for XML)解析是一种基于指针的解析方式,可以按需读取XML数据,适用于处理大型XML文件。

适用场景

  • 需要基于事件流的解析方式。
  • 需要从XML文件中按需提取数据。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.Characters;
import java.io.FileReader;

public class StAXParserExample {
public static void main(String[] args) {
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new FileReader("example.xml"));

while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.isStartElement()) {
StartElement startElement = event.asStartElement();
if (startElement.getName().getLocalPart().equals("employee")) {
String id = startElement.getAttributeByName(new QName("id")).getValue();
System.out.println("Employee ID: " + id);
} else if (startElement.getName().getLocalPart().equals("name")) {
event = eventReader.nextEvent();
System.out.println("Name: " + event.asCharacters().getData());
} else if (startElement.getName().getLocalPart().equals("age")) {
event = eventReader.nextEvent();
System.out.println("Age: " + event.asCharacters().getData());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

4. JAXB解析

JAXB(Java Architecture for XML Binding)解析通过注解将Java对象与XML元素映射,适用于需要将XML与Java对象相互转换的场景。

适用场景

  • 需要将XML与Java对象相互转换。
  • 需要使用Java对象直接操作XML数据。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.File;

@XmlRootElement
class Employee {
private String id;
private String name;
private int age;

// Getters and setters

@XmlElement
public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

@XmlElement
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@XmlElement
public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

public class JAXBExample {
public static void main(String[] args) {
try {
// Marshalling: Java object to XML
Employee employee = new Employee();
employee.setId("1");
employee.setName("John Doe");
employee.setAge(30);

JAXBContext context = JAXBContext.newInstance(Employee.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(employee, new File("employee.xml"));

// Unmarshalling: XML to Java object
Unmarshaller unmarshaller = context.createUnmarshaller();
Employee emp = (Employee) unmarshaller.unmarshal(new File("employee.xml"));
System.out.println("Employee ID: " + emp.getId());
System.out.println("Name: " + emp.getName());
System.out.println("Age: " + emp.getAge());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}

5. 第三方库(Jsoup 和 JDOM)

Jsoup

Jsoup 是一个Java的HTML解析库,也可以用于解析XML,提供了方便的DOM操作和数据提取功能。

适用场景

  • 需要解析HTML格式的XML。
  • 需要方便的DOM操作和数据提取。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

public class JsoupExample {
public static void main(String[] args) {
try {
File input = new File("example.xml");
Document doc = Jsoup.parse(input, "UTF-8", "", org.jsoup.parser.Parser.xmlParser());

Elements employees = doc.getElementsByTag("employee");
for (Element employee : employees) {
System.out.println("Employee ID: " + employee.attr("id"));
System.out.println("Name: " + employee.getElementsByTag("name").text());
System.out.println("Age: " + employee.getElementsByTag("age").text());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

JDOM

JDOM 是一个专门为Java开发的XML解析库,提供了简洁和高效的API来处理XML文档。

适用场景

  • 需要一个简单且强大的XML解析库。
  • 需要高效的DOM操作。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.jdom2.Document;
import org.jdom2.Element;
import org.j

dom2.input.SAXBuilder;

import java.io.File;

public class JDOMExample {
public static void main(String[] args) {
try {
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(new File("example.xml"));

Element rootElement = document.getRootElement();
System.out.println("Root element: " + rootElement.getName());

for (Element employee : rootElement.getChildren("employee")) {
System.out.println("Employee ID: " + employee.getAttributeValue("id"));
System.out.println("Name: " + employee.getChildText("name"));
System.out.println("Age: " + employee.getChildText("age"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

选型建议

  • DOM:适合处理小型XML文件,需要对文档进行多次遍历或修改时使用。
  • SAX:适合处理大型XML文件,需要快速读取数据时使用。
  • StAX:适合处理大型XML文件,需要基于事件流的解析方式时使用。
  • JAXB:适合需要将XML与Java对象相互转换的场景。
  • Jsoup:适合解析HTML格式的XML,需要方便的DOM操作和数据提取时使用。
  • JDOM:适合需要简单且强大的XML解析库,高效的DOM操作时使用。

根据项目需求和复杂度选择最合适的XML解析方式,能够提高开发效率和系统性能。