hello xmlbeans 2
Dec
源起
在 spring-osgi 練習中,使用 Apache Xmlbeans 來做 XML 的工作,這裡紀錄一些常見的問題。
java 5
加個 javasource 參數可以不用陣列,改回傳有型的 List,方便使用。
<xmlbean schema=”schemas” destfile=”dist/Schemas.jar” classgendir=”build” srcgendir=”src” javasource=”1.5” />
基本產出過程
ProjectDocument foodoc =
ProjectDocument.Factory.newInstance();
ProjectType pj = foodoc.addNewProject();
ProfileType pf = pj.addNewProfile();
pf.setName("HAHA");
pf.setSummary("SUMMARY");
XmlOptions opts = new XmlOptions();
opts.setSavePrettyPrint();
// namespace
HashMap suggestedPrefixes = new HashMap(); suggestedPrefixes.put(
"http://config.service.haha/ns/project", "so");
opts.setSaveSuggestedPrefixes(suggestedPrefixes);
foodoc.save(System.out, opts);
會輸出下列結果 :
<?xml version="1.0" encoding="UTF-8"?>
<so:project xmlns:so="http://config.service.haha/ns/project">
<profile>
<name>HAHA</name>
<summary>SUMMARY</summary>
</profile>
</so:project>
xpath
xpath 的支援有限,而且不同版本之間不是相當穩定, 採用的 namespace 方式似乎和文件本身有很大關係, 不支援屬性的比對來取出 id 小於 10 的原因還要再查。
String ns = "declare namespace pj='http://extremepattern.com/ns/project';"; // error $this/pj:project/pj:requirements/pj:summaryGoal; // error $this/pj:project/pj:requirements; // error $this/pj:project/requirements/summaryGoal[@id < 10]; String xpathStatement = ns + "$this//pj:project/requirements/summaryGoal"; XmlObject[] queryResult = pinfo.getProjectDoc().selectPath(xpathStatement);
另外就是取出的物件並非拷貝版,任何更動都會改變原文件。
http://xmlbeans.apache.org/docs/2.0.0/guide/conSelectingXMLwithXQueryPathXPath.html
foreach
常常需要取出部份的符合條件的節點,可以用 xpath 或是自己 foreach 去取出來。
List<SummaryGoalType> summaryList = reqs.getSummaryGoalList();
List<SummaryGoalType> result = new ArrayList<SummaryGoalType>();
for (SummaryGoalType type : summaryList) {
if (type.getId() < 10 ) {
result.add((SummaryGoalType) type.copy());
}
}
和 xpath 相比,可以比較的方式更複雜,也可選擇取出複製版或是原始版, schema 變動反應 refactoring 需求時,編譯會直接出問題無法過,用 xpath 方式 需要用 unit test 去反應出來,編譯可能不會出問題。
srcgetidr
srcgendir 輸出的東西和 jar 的東西不一樣,只有使用產生的程式碼可以 編譯,但是執行時期會出現錯誤。
<target name="schmea.to.java"> <xmlbean schema="schemas" destfile="schemas/haha.service.config.schemas.jar" fork="false" classpathref="supportlib.classpath" javasource="1.5" srcgendir="xsdsrc" /> </target>
所以在開發 bundle 時候,需要將 haha.service.config.schemas.jar 掛起來,等到要包裝時,再把 haha.service.config.schemas.jar 打散,一起放到 jar 根目錄去。
參考之前的做法 build-xml-in-haha-remix-foo 。
觀察
- 需要跟 JAXB 2.0 比較看看。