將 XML 文件解析為純文本輸出,需遞歸遍歷所有節點,提取標籤名、屬性、文本內容。
| 解析器 | 特點 | 適用場景 | 內存佔用 |
|---|---|---|---|
| DOM (Document Object Model) | 一次性載入整棵樹,隨機訪問,易修改 | 小文件、需頻繁增刪改查 | 高(整文檔入內存) |
| SAX (Simple API for XML) | 事件驅動流式讀取,只讀,不可回溯 | 大文件、單次順序讀取 | 極低 |
| StAX (Streaming API for XML) | 拉取式流式讀取,可控制解析進度 | 大文件、需部分跳過/提前終止 | 低 |
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class XmlToText {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("input.xml"));
doc.getDocumentElement().normalize();
StringBuilder sb = new StringBuilder();
printNode(doc.getDocumentElement(), sb, 0);
System.out.println(sb.toString());
}
static void printNode(Node node, StringBuilder sb, int depth) {
String indent = " ".repeat(depth);
switch (node.getNodeType()) {
case Node.ELEMENT_NODE:
sb.append(indent).append("<").append(node.getNodeName());
NamedNodeMap attrs = node.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
Node attr = attrs.item(i);
sb.append(" ").append(attr.getNodeName()).append("=\"").append(attr.getNodeValue()).append("\"");
}
sb.append(">\n");
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
printNode(children.item(i), sb, depth + 1);
}
sb.append(indent).append("</").append(node.getNodeName()).append(">\n");
break;
case Node.TEXT_NODE:
String text = node.getNodeValue().trim();
if (!text.isEmpty()) sb.append(indent).append(text).append("\n");
break;
// 可按需處理 CDATA、註釋等
}
}
}
// 實現 DefaultHandler,重寫 startElement、characters、endElement
// 在 characters 中累積文本,startElement/endElement 輸出標籤
