源起
幾個專案用過 XMLBeans,還不錯用,之前評估過 JAXB 1.0 版本,有兩個問題,
一是 XML Schema 支援有點問題,一是 JAXB 當時有商業授權等議題。
這些專案是採 XML Schema 為主的做法,也就是需要先由客戶端決定商業領域的語法,
交付寫好的 schema,那時 JAXB 1 沒辦法很方便的foo.xsd 轉 foo.java,
而 foo.xsd 一直改到後期會越來越複雜,一堆的 complex type,所以那時找到能
符合專案 schema 與授權的方案是 BEA 釋出的 Apache XMLBeans。
不過時過境遷,現在 JAXB 2 授權也改了,支援 XML schema 應該也
比較好,同時 JavaSE6 已經內建支援,於是來玩看看。
http://download.java.net/jdk6/docs/technotes/guides/xml/jaxb/index.html
scheam-first or code-first
如果先寫 schema 的話,需要使用 xjc,就 eclipse 來說,使用 ant 比較方便。
不過 com.sun.tools.xjc.XJCTask 並不存在 JRE 中,需要下載 jaxb-xjc.jar 來用。
https://jaxb.dev.java.net/nonav/2.0.2/docs/xjcTask.html
https://jaxb.dev.java.net/
用 xjc 產生 java 碼後,就可以開始用。
ProjectType pj = new ProjectType();
...[SKIP]
ObjectFactory objFactory = new ObjectFactory();
JAXBElement<ProjectType> je = objFactory.createProject(pj);
JAXBContext jc = JAXBContext.newInstance(ProjectType.class);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
簡單 marshaller.marshal(jaxbElement, System.out) 的結果。
<ns2:project xmlns:ns2="http://config.service.haha/ns/project">
<profile>
<name>FOO PROJECT</name>
</profile>
</ns2:project>
更換 ns2
指定預設或是更動命名空間的 prefix 並不在 JAXB2 的規格 (JSR-222 spec) 中,
所以 JAVA6 平台無法提供這類的 marshaller 機制,要用 JAXB2 RI 才可以,
因為有的 schema 的 prefix 名稱是定死的,不支援這個會比較麻煩。
// RI 才有支援,需要 jaxb-impl.jar,JAVA6 不包含
marshller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
new NamespacePrefixMapper() {
@Override
public String getPreferredPrefix(String nsuri,
String suggestion, boolean requirePrefix) {
// 無法調成 default 只能改掉。用 "" 無效 ?
if ("http://config.service.haha/ns/project".equals(nsuri))
return "pj";
return suggestion;
}
});
結果輸出
<pj:project xmlns:pj="http://config.service.haha/ns/project">
<profile>
<name>FOO PROJECT</name>
</profile>
</pj:project>
取部份 XML 輸出
之前用 XMLBeans 都用複製 copy 模式建立另一個文件來修改取出需要的部份,
JAXB 似乎沒有這類方式,需要建立兩個物件複製。
haha.remix.jaxb
基本上就是轉包 jaxb-api.jar, jaxb-impl.jar, jsr173_1.0_api.jar 供 OSGi 平台使用,
JAVA6 雖然有支援 JAXB2,但是需要 com.sun.xml.bind.namespacePrefixMapper 的情況下,
還是要使用附加的 jaxb-impl.jar。
另外使用 haha.remix.jaxb 讓 JAVA5 也一樣可以用。
JAVA6
根據 Java 6 Leads Out of the Box Server Performance
的說法,這個快上很多的出場預設性能蠻吸引人的。
觀察
- 因為 JAXB 已經是個標準,關於 JAXB 的用法還要再深入觀察。
- 個人目前用起來 XMLBeans 比較直覺,也有可能是用習慣的關係。
- 簡單的綁定, JAVA 6 是個不錯的現成平台,如果要更細部的支援,無可避免還是要加 jar 到平台上,這時 JAXB2 RI 或是 XMLBeans 就看哪個用的順手,功能也都可以提供為主。