用Digester处理一些结构比较简单的XML有很多文章,如何处理类似于下面下面的XML呢? 我只是找到了一篇讨论类似结构的文章。
下面XML的特殊之处在于第二层(APPSIMULATOR之下)有三种不同的结构:
INERACTION下面又定义了一个EVENT列表,EVENT下面又定义了一个APP列表。
JSON也是一种常用的数据交换格式,如果尝试把下面的XML转换为JSON,表示上没有XML清晰。在序列化和反序列化方面,复杂的JSON反序列化效果不尽人意。个人感觉:对于简单结构的数据,JSON和XML表示上不相上下,处理上JSON有一些优势;对于复杂结构的数据,XML表示和处理上均占优势。试图用FastJSON来反序列化相同的内容,没有成功,如果你有办法请告诉我。
<?xml version="1.0" encoding="UTF-8"?> <APPSIMULATOR> <VERSION>1.0</VERSION> <APPLIST> <APP name = "APPA" id= "1" /> <APP name = "APPB" id= "2" /> <APP name = "APPC" id= "3" /> </APPLIST> <INTERACTION> <EVENT name = "LAUNCH" id = "2"> <APP name = "APPB" id= "2" order = "1"> <ACTION>RUN</ACTION> <TIME>20</TIME> </APP> </EVENT> <EVENT name = "EVENTA" id = "3"> <APP name = "APPB" id= "2" order = "1"> <ACTION>RUN</ACTION> <TIME>20</TIME> </APP> <APP name = "APPC" id= "3" order = "2"> <ACTION>RUN</ACTION> <TIME>20</TIME> </APP> </EVENT> </INTERACTION> </APPSIMULATOR>
为使用Digester反序列化上面的文件,需要先编写相应的Bean。先看APPLIST中APP的Bean:
public class LayoutApp { String name; int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
然后是INTERACTION/EVENT/APP的Bean:
public class LayoutEventApp { String name; int id; int order; String action; float time; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public float getTime() { return time; } public void setTime(float time) { this.time = time; } }
然后是INTERACTION/EVENT的Bean:
public class LayoutEvent { String name; int id; List<LayoutEventApp> apps = new ArrayList<LayoutEventApp>(); public void addEventApp(LayoutEventApp app){ apps.add(app); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public List<LayoutEventApp> getEvents() { return apps; } public void setEvents(List<LayoutEventApp> apps) { this.apps = apps; } }
注意其中有个方法public void addEventApp(LayoutEventApp app),它用来为创建EVENT下面的APP列表。
然后是INTERACTION的Bean:
public class LayoutInteraction { List<LayoutEvent> events = new ArrayList<LayoutEvent>(); public void addLayoutEvent(LayoutEvent event){ events.add(event); } public List<LayoutEvent> getEvents() { return events; } public void setEvents(List<LayoutEvent> events) { this.events = events; } }
注意它同样有个类似方法public void addLayoutEvent(LayoutEvent event),用来创建INTERACTION下面的EVENT列表。
最后是Root的Bean:
public class LayoutAppSimulator { String version; List<LayoutApp> apps = new ArrayList<LayoutApp>(); LayoutInteraction interaction; public void addApp(LayoutApp app){ apps.add(app); } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public List<LayoutApp> getApps() { return apps; } public void setApps(List<LayoutApp> apps) { this.apps = apps; } public LayoutInteraction getInteraction() { return interaction; } public void setInteraction(LayoutInteraction interaction) { this.interaction = interaction; } }
它有两个方法public void addApp(LayoutApp app)和public void setInteraction(LayoutInteraction interaction)。前一个用来创建APPLIST列表,后一个用来赋值(单独赋值的原因在于创建LayoutAppSimulator时,LayoutInteraction还没有构建出来,它直到解析完整个XML之后才构建完成)。
最后看看反序列化的代码:
public static LayoutAppSimulator Unserialize() throws FileNotFoundException, IOException, SAXException{ Digester digester = new Digester(); digester.setValidating(false); // (1) VERSION + APPLIST + INTERACTION digester.addObjectCreate("APPSIMULATOR", LayoutAppSimulator.class); digester.addBeanPropertySetter("APPSIMULATOR/VERSION", "version"); // (2) APPLIST digester.addObjectCreate("APPSIMULATOR/APPLIST/APP", LayoutApp.class); digester.addSetProperties("APPSIMULATOR/APPLIST/APP"); digester.addSetNext("APPSIMULATOR/APPLIST/APP", "addApp"); //LayoutAppSimulator.addApp // (2) INTERACTION digester.addObjectCreate("APPSIMULATOR/INTERACTION", LayoutInteraction.class); // (3) EVENT digester.addObjectCreate("APPSIMULATOR/INTERACTION/EVENT", LayoutEvent.class); digester.addSetProperties("APPSIMULATOR/INTERACTION/EVENT"); // (4) APP digester.addObjectCreate("APPSIMULATOR/INTERACTION/EVENT/APP", LayoutEventApp.class); digester.addSetProperties("APPSIMULATOR/INTERACTION/EVENT/APP"); digester.addBeanPropertySetter("APPSIMULATOR/INTERACTION/EVENT/APP/ACTION", "action"); digester.addBeanPropertySetter("APPSIMULATOR/INTERACTION/EVENT/APP/TIME", "time"); // (4) APP digester.addSetNext("APPSIMULATOR/INTERACTION/EVENT/APP", "addEventApp"); // LayoutEvent.addEventApp // (3) EVENT digester.addSetNext("APPSIMULATOR/INTERACTION/EVENT", "addLayoutEvent"); //LayoutInteraction.addLayoutEvent // (1) VERSION + APPLIST + INTERACTION digester.addSetNext("APPSIMULATOR/INTERACTION", "setInteraction"); LayoutAppSimulator sim = (LayoutAppSimulator)digester.parse(new FileInputStream("\\layout_descriptor_doc_example.xml")); return sim; }
上面的代码只需要懂Digester几个常用API即可。解决的关键在于分析的方法(分层):分别处理XML的每一层,注意顺序 1 2 3 4 3 2 1。
常见的错误:
祝你好运