簡介
Apache Commons的Digester套件可以將以xml格式表示的資料,剖析後轉成Java的model物件。假設我們的資料格式如下:
<?xml version='1.0'?>
<addressBook>
<person id="1" category="acquaintance">
<name>Gonzo</name>
<email type="business">gonzo@muppets.com</email>
<address>
<type>home</type>
<street>123 Maine
Ave.</street>
<city>Las Vegas</city>
<state>NV</state>
<zip>01234</zip>
<country>USA</country>
</address>
<address>
<type>business</type>
<street>234
Maple Dr.</street>
<city>Los Angeles</city>
<state>CA</state>
<zip>98765</zip>
<country>USA</country>
</address>
</person>
<person id="2" category="rolemodel">
<name>Kermit</name>
<email type="business">kermit@muppets.com</email>
<email type="home">kermie@acme.com</email>
<address>
<type>business</type>
<street>987
Brown Rd</street>
<city>Las Cruces</city>
<state>NM</state>
<zip>75321</zip>
<country>USA</country>
</address>
</person>
</addressBook>
首先,我們需要準備AddressBook、Persion、Address的類別,並建立對應的屬性與getter/setter方法,來映射這份XML的資料。接下來就輪到Digester上場了(完整source code按此)。
由AddressBook類別的main方法開始:
public static void
main(String[] args) {
logger.info("main() - start");
try {
AddressBook
addressBook = new AddressBook("example.xml");
logger.info("addressBooktoString() = " + addressBook.toString());
} catch
(Exception ex) {
logger.error("main() - exception: ", ex);
}
logger.info("main() - end");
}
建構子中呼叫了parse()方法負責主要的剖析與映射工作:
public
AddressBook(String fileName) throws Exception {
super();
this.parse(fileName);
}parse()方法中展示了使用Digester的基本程式寫法架構,並再次呼叫addDigesterRules()方法負責物件與屬性的映射工作:
protected void parse(String fileName) throws
IOException, FileNotFoundException, SAXException, IllegalArgumentException {
if
((fileName == null) || (fileName.toString().length() <= 0)) {
throw new
IllegalArgumentException("parameter
'fileName' is required");
}
File file
= new File(fileName);
logger.debug("file = " + file.getAbsolutePath());
if
(!file.exists()) {
throw new
FileNotFoundException(String.format("the file '%s' is not exist.", file.getAbsolutePath()));
}
// Create a Digester instance
Digester
digester = new Digester();
digester.push(this);
//
Add rules to the digester that will be triggered while parsing occurs.
this.addDigesterRules(digester);
// Parse the input file.
digester.parse(file);
}
addDigesterRules()方法內容:
protected void addDigesterRules(Digester digester) {
digester.addObjectCreate("addressBook/person", Person.class);
digester.addSetProperties("addressBook/person");
digester.addSetNext("addressBook/person", "addPerson");
digester.addCallMethod("addressBook/person/name", "setName", 1);
digester.addCallParam("addressBook/person/name", 0);
digester.addCallMethod("addressBook/person/email", "addEmail", 2);
digester.addCallParam("addressBook/person/email", 0, "type");
digester.addCallParam("addressBook/person/email", 1);
digester.addObjectCreate("addressBook/person/address", Address.class);
digester.addSetNext("addressBook/person/address", "addAddress");
digester.addSetNestedProperties("addressBook/person/address");
}
執行結果:
[2014/07/18 14:34:17]
INFO tw.blogspot.saminjava.demo.digester.AddressBook:142 - main() -
start
[2014/07/18 14:34:18]
INFO tw.blogspot.saminjava.demo.digester.AddressBook:146 -
addressBooktoString() = tw.blogspot.saminjava.demo.digester.AddressBook@444cee32[personList=[tw.blogspot.saminjava.demo.digester.Person@23394894[id=1,name=Gonzo,emailMap={business=gonzo@muppets.com},addressList=[tw.blogspot.saminjava.demo.digester.Address@5cbfe9d[type=home,street=123
Maine Ave.,city=Las Vegas,state=NV,zip=01234,country=USA],
tw.blogspot.saminjava.demo.digester.Address@13b8f864[type=business,street=234
Maple Dr.,city=Los Angeles,state=CA,zip=98765,country=USA]]],
tw.blogspot.saminjava.demo.digester.Person@54bb7759[id=2,name=Kermit,emailMap={home=kermie@acme.com,
business=kermit@muppets.com},addressList=[tw.blogspot.saminjava.demo.digester.Address@5f989f84[type=business,street=987
Brown Rd,city=Las Cruces,state=NM,zip=75321,country=USA]]]]]
[2014/07/18 14:34:18] INFO tw.blogspot.saminjava.demo.digester.AddressBook:152
- main() - end