Apache XMLBeans 提供 XML Schema (XSD) 驅動的 Java 類別生成,支援增量解析 (僅解析存取部分)、高效 xget 方法、完整 Schema 驗證、物件序列化等特性,是 Web Services、BPEL、規則引擎等領域的主流資料綁定技術。本文從環境建置、Schema 編譯、解析/建立 XML 文件、多全域元素處理、效能優勢到驗證機制全面解析。
bin/ 加入 PATH,lib/xbean.jar 加入 CLASSPATHscomp -out weather.jar weather_latlong.xsd
<xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<xsd:element name="Weather">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Temperature" type="xsd:float"/>
<xsd:element name="Humidity" type="xsd:float"/>
<xsd:element name="Visibility" type="xsd:float"/>
<xsd:element name="Datetime" type="xsd:dateTime"/>
</xsd:sequence>
<xsd:attribute ref="Zipcode"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="Latlong">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Latitude" type="xsd:string"/>
<xsd:element name="Longitude" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute ref="Zipcode"/>
</xsd:complexType>
</xsd:element>
<xsd:attribute name="Zipcode" type="xsd:string"/>
</xsd:schema>
定義兩個全域元素 Weather、Latlong 及共用屬性 Zipcode。
編譯產生 5 個介面:
WeatherDocument、WeatherDocument$WeatherLatlongDocument、LatlongDocument$LatlongZipcodeAttribute命名規則:Document 尾 = 文檔元素;$ElementName = 全域元素;Attribute 尾 = 全域屬性。巢狀類型產生內部介面 (如 Employee$Jobstatus)。
對應 46 種 XSD 內建類型,每種提供雙方法:
// 以 xsd:float 為例
float getVisibility(); // 轉換為原生 Java 類型
XmlFloat xgetVisibility(); // 直接返回 XMLBeans 類型 (效能更高)
xget 避免類型轉換開銷,適合高效能場景。
String filePath = "weatherInput.xml";
File inputXMLFile = new File(filePath);
WeatherDocument weatherDoc = WeatherDocument.Factory.parse(inputXMLFile);
WeatherDocument.Weather weatherElement = weatherDoc.getWeather();
Calendar timeStamp = weatherElement.getDatetime();
System.out.println("Weather details of zipcode " + weatherElement.getZipcode() + " at " + timeStamp);
System.out.println("Temperature is " + weatherElement.getTemperature());
System.out.println("Humidity is " + weatherElement.getHumidity());
System.out.println("Visibility is " + weatherElement.getVisibility());
XmlObject xmlObj = XmlObject.Factory.parse(inputXMLFile);
if (xmlObj instanceof noNamespace.WeatherDocument) {
WeatherDocument weatherDoc = (WeatherDocument) xmlObj;
// ... 處理 Weather
} else if (xmlObj instanceof noNamespace.LatlongDocument) {
LatlongDocument latLongDoc = (LatlongDocument) xmlObj;
LatlongDocument.Latlong latLongElement = latLongDoc.getLatlong();
System.out.println("Latlong details of zipcode " + latLongElement.getZipcode());
System.out.println("Latitude is " + latLongElement.getLatitude());
System.out.println("Longitude is " + latLongElement.getLongitude());
} else {
System.out.println("Input xml document doesn't conform to weather_latlong.xsd");
}
關鍵:XmlObject.Factory.parse() 返回具體文檔類型,透過 instanceof 判斷分派。
LatlongDocument latLongDoc = LatlongDocument.Factory.newInstance();
LatlongDocument.Latlong latLongElement = latLongDoc.addNewLatlong();
latLongElement.setZipcode("91023");
latLongElement.setLatitude("33.8792");
latLongElement.setLongitude("117.8974");
// 美化輸出配置
XmlOptions xmlOptions = new XmlOptions();
xmlOptions.setSavePrettyPrint();
xmlOptions.setSavePrettyPrintIndent(4);
String xmlStr = latLongDoc.xmlText(xmlOptions);
System.out.println("XML Instance Document is :\n" + xmlStr);
輸出:
<Latlong Zipcode="91023">
<Latitude>33.8792</Latitude>
<Longitude>117.8974</Longitude>
</Latlong>
| 特性 | 說明 |
|---|---|
| 增量解析 | 僅解析實際存取的節點,未存取部分不佔記憶體/CPU,遠優於 DOM 全樹解析 |
| xget 高效存取 | 直接返回 XMLBeans 類型避免轉換,適合大量資料處理 |
| 完整 Schema 驗證 | 解析時驗證;運行期透過 setter/getter 持續強制約束 (如 QName 前綴必須可解析) |
| 可序列化 | 支援 RMI 傳遞、字元/位元組流存儲 |
| 名稱映射配置 | XML 名稱變更時無需修改 Java 代碼,透過配置映射 |
Factory.parse() 根據 Schema 驗證輸入 XMLWeb Services (SOAP 訊息綁定)、BPEL/BPML 流程引擎、基於規則的 XML 轉換引擎、配置檔管理等需強型別、高效能、Schema 驗證的場景。
XMLBeans 以增量解析、xget 高效存取、近 100% Schema 支援、雙層驗證 四大特性,確立 XML-Java 資料綁定高效能標準。對於需處理大型 XML、嚴格遵循 Schema、整合 Web Services 的企業級應用,是極佳選擇。