XML 在 Java 體系中無處不在:web.xml、pom.xml、Spring 配置、MyBatis Mapper、JAXB 綁定、SOAP 訊息、JMS 郵件格式。掌握核心概念不僅為面試,更為日常除錯、架構選型。本文在上一篇基礎上,補充 Java 視角的程式碼範例、常見庫、效能陷阱。
<?xml version="1.0" encoding="UTF-8"?> 宣告、編碼聲明的重要性(解析器按此解碼)。// Schema 驗證
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("order.xsd"));
Validator v = schema.newValidator();
v.validate(new StreamSource(new File("order.xml"))); // 拋 SAXException 即不合法
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
String expr = "//order[@status='SHIPPED']/item/sku/text()";
NodeList nl = (NodeList) xpath.evaluate(expr, doc, XPathConstants.NODESET);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(new StreamSource("order2html.xsl"));
t.transform(new StreamSource("order.xml"), new StreamResult(new File("order.html")));
doc.createElementNS(ns, "tag")、elem.setAttribute("id", "1")、elem.getTextContent()。DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream) 拋 SAXParseException 即不合法。xpath.setNamespaceContext(ctx)、DocumentBuilderFactory.setNamespaceAware(true)(預設 false,易導致 XPath 查無結果)。DocumentBuilder)。DefaultHandler)或 StAX(XMLStreamReader)。// 生成
CDATASection cdata = doc.createCDATASection("<script>alert(1)</script>");
elem.appendChild(cdata);
// 解析:SAX handler 的 characters() 會收到原始文本,無需手動轉義
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD)
public class Order { @XmlAttribute Long id; @XmlElement List<Item> items; }
// 封送/解封送
JAXBContext ctx = JAXBContext.newInstance(Order.class);
Marshaller m = ctx.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(order, System.out);
Unmarshaller u = ctx.createUnmarshaller(); Order o = (Order) u.unmarshal(new File("order.xml"));
| 場景 | 推薦庫 | 特點 |
|---|---|---|
| 標準綁定 | JAXB (JDK 6-10 內建, 11+ 需額外引入) | 註解驅動、標準 API |
| 高效能解析 | Woodstox (StAX 實作) | 快速、低記憶體、支援非標準 XML |
| 大文件隨機訪問 | VTD-XML | 索引式、XPath 極快、記憶體映射 |
| 簡單配置讀取 | Dom4j / JDOM2 | API 友善、XPath 整合好 |
| JSON⇄XML 轉換 | Jackson XmlMapper / org.json | 雙向、流式 |
dbf.setFeature("https://apache.org/xml/features/disallow-doctype-decl", true)、setFeature("https://xml.org/sax/features/external-general-entities", false)、setFeature("https://xml.org/sax/features/external-parameter-entities", false)。DocumentBuilderFactory.setNamespaceAware(true) 預設關閉,導致 XPath 查詢失效,務必開啟。InputSource.setEncoding("UTF-8")。