在 Java 生態中處理 XML,核心面臨兩大任務:解析與生成。主流方案分為標準庫與第三方庫兩大陣營:
引入依賴(Maven 坐標示例):
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
標準庫 javax.xml.parsers、org.w3c.dom、org.xml.sax 無需額外引入。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("books.xml"));
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
Element book = (Element) books.item(i);
String id = book.getAttribute("id");
NodeList children = book.getChildNodes();
for (int k = 0; k < children.getLength(); k++) {
if (children.item(k).getNodeType() == Node.ELEMENT_NODE) {
System.out.println(children.item(k).getNodeName() + ": " + children.item(k).getTextContent());
}
}
}
Document doc = builder.newDocument();
Element root = doc.createElement("bookstore");
Element book = doc.createElement("book");
book.setAttribute("id", "1");
Element name = doc.createElement("name");
name.setTextContent("小王子");
book.appendChild(name);
root.appendChild(book);
doc.appendChild(root);
TransformerFactory tfFactory = TransformerFactory.newInstance();
Transformer transformer = tfFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(doc), new StreamResult(new File("out.xml")));
public class BookHandler extends DefaultHandler {
private List<Book> books = new ArrayList<>();
private Book current;
private StringBuilder text = new StringBuilder();
@Override public void startElement(String uri, String local, String qName, Attributes attrs) {
if ("book".equals(qName)) { current = new Book(); current.setId(attrs.getValue("id")); }
text.setLength(0);
}
@Override public void characters(char[] ch, int start, int len) { text.append(ch, start, len); }
@Override public void endElement(String uri, String local, String qName) {
if (current == null) return;
switch (qName) {
case "name": current.setName(text.toString()); break;
case "author": current.setAuthor(text.toString()); break;
// ... 其他字段
case "book": books.add(current); current = null; break;
}
}
public List<Book> getBooks() { return books; }
}
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
BookHandler handler = new BookHandler();
parser.parse(new File("books.xml"), handler);
SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler handler = tf.newTransformerHandler();
Transformer tr = handler.getTransformer();
tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tr.setOutputProperty(OutputKeys.INDENT, "yes");
handler.setResult(new StreamResult(new FileOutputStream("sax_out.xml")));
handler.startDocument();
AttributesImpl attrs = new AttributesImpl();
handler.startElement("", "", "bookstore", attrs);
for (Book b : books) {
attrs.clear(); attrs.addAttribute("", "", "id", "", b.getId());
handler.startElement("", "", "book", attrs);
// 依次寫入 name、author 等子元素
handler.endElement("", "", "book");
}
handler.endElement("", "", "bookstore");
handler.endDocument();
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new FileInputStream("books.xml"));
Element root = doc.getRootElement();
List<Element> books = root.getChildren();
for (Element book : books) {
String id = book.getAttributeValue("id");
for (Element child : book.getChildren()) {
String name = child.getName(), value = child.getValue();
// 映射到 Book 對象
}
}
Element rss = new Element("rss").setAttribute("version", "2.0");
Document doc = new Document(rss);
Element channel = new Element("channel");
rss.addContent(channel);
channel.addContent(new Element("title").setText("國內國際新聞"));
Format format = Format.getPrettyFormat();
format.setEncoding("GBK");
new XMLOutputter(format).output(doc, new FileOutputStream("jdom_out.xml"));
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("books.xml"));
Element root = doc.getRootElement();
for (Iterator<Element> it = root.elementIterator(); it.hasNext(); ) {
Element book = it.next();
for (Attribute attr : book.attributes()) {
System.out.println(attr.getName() + "=" + attr.getValue());
}
for (Iterator<Element> it2 = book.elementIterator(); it2.hasNext(); ) {
Element child = it2.next();
System.out.println(child.getName() + "=" + child.getStringValue());
}
}
Document doc = DocumentHelper.createDocument();
Element rss = doc.addElement("rss").addAttribute("version", "2.0");
Element channel = rss.addElement("channel");
channel.addElement("title").setText("國內最新新聞");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
XMLWriter writer = new XMLWriter(new FileOutputStream("dom4j_out.xml"), format);
writer.write(doc); writer.close();
典型 1MB XML 文件解析耗時(僅供參考,視機器而定):
選型建議: