
在Java中解析XML文件有多种方式,每种方式都有其适用场景和特点。常见的XML解析方式包括:
- DOM(Document Object Model)解析
- SAX(Simple API for XML)解析
- StAX(Streaming API for XML)解析
- JAXB(Java Architecture for XML Binding)解析
- 第三方库(如 Jsoup 和 JDOM)
下面是对每种方式的详细介绍和示例代码。
1. DOM解析
DOM(Document Object Model)解析是将整个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文件,遇到不同的事件(如开始标签、结束标签等)时调用相应的处理方法。
适用场景
示例代码
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;
@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 { 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"));
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解析方式,能够提高开发效率和系统性能。