dom方式:个人理解类似.net的xmldocument,解析的时候效率不高,占用内存,不适合大xml的解析;
sax方式:基于事件的解析,当解析到xml的某个部分的时候,会触发特定事件,可以在自定义的解析类中定义当事件触发时要做得事情;个人感觉一种很另类的方式,不知道.net体系下是否有没有类似的方式?
stax方式:个人理解类似.net的xmlreader方式,效率高,占用内存少,适用大xml的解析;
不过sax方式之前也用过,本文主要介绍jaxb,这里只贴下主要代码:
import java.util.arraylist; import java.util.list; import org.xml.sax.attributes; import org.xml.sax.saxexception; import org.xml.sax.helpers.defaulthandler; public class configparser extends defaulthandler { private string currentconfigsection; public sysconfigitem sysconfig; public list<interfaceconfigitem> interfaceconfiglist; public list<ftpconfigitem> ftpconfiglist; public list<adapterconfigitem> adapterconfiglist; public void startdocument() throws saxexception { sysconfig = new sysconfigitem(); interfaceconfiglist = new arraylist<interfaceconfigitem>(); ftpconfiglist = new arraylist<ftpconfigitem>(); adapterconfiglist = new arraylist<adapterconfigitem>(); } public void enddocument() throws saxexception { } public void startelement(string uri, string localname, string qname, attributes attributes) throws saxexception { if (qname.equalsignorecase("item") && attributes.getlength() > 0) { if (currentconfigsection.equalsignorecase("sysconfigitem")) { sysconfig = new sysconfigitem(attributes); } else if (currentconfigsection.equalsignorecase("interfaceconfigitems")) { interfaceconfiglist.add(new interfaceconfigitem(attributes)); } else if (currentconfigsection.equalsignorecase("ftpconfigitems")) { ftpconfiglist.add(new ftpconfigitem(attributes)); } else if (currentconfigsection.equalsignorecase("adapterconfigitems")) { adapterconfiglist.add(new adapterconfigitem(attributes)); } } else { currentconfigsection = qname; } } public void endelement(string uri, string localname, string qname) throws saxexception { } public void characters(char ch[], int start, int length) throws saxexception { } }
import java.lang.reflect.field; import java.text.dateformat; import java.text.parseexception; import java.text.simpledateformat; import java.util.date; import org.xml.sax.attributes; public class configitembase { private static dateformat dateformat = new simpledateformat("yyyy-mm-dd hh:mm:ss"); public configitembase() { } /** * 目前只支持几种常用类型 如果需要支持其他类型,请修改这里的代码 * * @param attributes */ public configitembase(attributes attributes) { class<?> cls = this.getclass(); field[] fields = cls.getdeclaredfields(); for (field field : fields) { string fieldtype = field.gettype().getsimplename(); for (int i = 0; i < attributes.getlength(); i++) { if (attributes.getqname(i).equalsignorecase(field.getname())) { field.setaccessible(true); try { if (fieldtype.equalsignorecase("string")) { field.set(this, attributes.getvalue(attributes.getqname(i))); } else if (fieldtype.equalsignorecase("integer")) { field.set(this, integer.valueof(attributes.getvalue(attributes.getqname(i)))); } else if (fieldtype.equalsignorecase("double")) { field.set(this, double.valueof(attributes.getvalue(attributes.getqname(i)))); } else if (fieldtype.equalsignorecase("date")) { field.set(this, getdate(attributes.getvalue(attributes.getqname(i)))); } else { system.out.println("warning:unhandler field(" + field.getname() + "-" + fieldtype + ")"); } } catch (illegalargumentexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } break; } } } } public string tostring() { string result = ""; class<?> cls = this.getclass(); string classnamestring = cls.getname(); result += classnamestring.substring(classnamestring.lastindexof('.') + 1, classnamestring.length()) + ":"; field[] fields = cls.getdeclaredfields(); for (field field : fields) { try { result += field.getname() + "=" + field.get(this) + ";"; } catch (illegalargumentexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } } return result; } /** * 处理时间类型属性(时间格式要求为:yyyy-mm-dd hh:mm:ss) * * @param datestring * @return */ private static date getdate(string datestring) { date date = null; try { date = dateformat.parse(datestring); } catch (parseexception e) { e.printstacktrace(); } return date; } }
下面重点介绍一下最方便的:jaxb(java architecture for xml binding)
这里用比较复杂的移动batchsyncorderrelationreq接口xml做为示例(感觉能解这个大家基本上够用了),报文格式如下(svccont里的cdata内容是报文体,太恶心了):
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <interboss> <version>0100</version> <testflag>0</testflag> <biptype> <bipcode>bip2b518</bipcode> <activitycode>t2101518</activitycode> <actioncode>0</actioncode> </biptype> <routinginfo> <origdomain>boss</origdomain> <routetype>routetype</routetype> <routing> <homedomain>xxxx</homedomain> <routevalue>routevalue</routevalue> </routing> </routinginfo> <transinfo> <sessionid>2013041017222313925676</sessionid> <transido>2013041017222313925676</transido> <transidotime>20130410172223</transidotime> <transidh></transidh> <transidhtime></transidhtime> </transinfo> <snreserve> <transidc></transidc> <convid></convid> <cutoffday></cutoffday> <osntime></osntime> <osnduns></osnduns> <hsnduns></hsnduns> <msgsender></msgsender> <msgreceiver></msgreceiver> <priority></priority> <servicelevel></servicelevel> <svcconttype></svcconttype> </snreserve> <response> <rsptype>rsptype</rsptype> <rspcode>rspcode</rspcode> <rspdesc>rspdesc</rspdesc> </response> <svccont><![cdata[<?xml version="1.0" encoding="utf-8" standalone="yes"?> <batchsyncorderrelationreq> <msgtransactionid>210001bip2b518130410172223651627</msgtransactionid> <reqnum>2</reqnum> <reqbody> <oprnumb>210001bip2b518130410172224341871</oprnumb> <subscriptioninfo> <oprtime>oprtime1</oprtime> <actionid>actionid1</actionid> <brand>brand1</brand> <efftime>efftime1</efftime> <expiretime>expiretime1</expiretime> <feeuser_id>feeuserid1</feeuser_id> <destuser_id>destuserid1</destuser_id> <actionreasonid>actionid1</actionreasonid> <servtype>servtype1</servtype> <subservtype>subservtype1</subservtype> <spid>spid1</spid> <spservid>spservid1</spservid> <accessmode>accessmode1</accessmode> <servparaminfo> <para_num>0</para_num> <para_info> <para_name></para_name> <para_value></para_value> </para_info> </servparaminfo> <feetype>feetype1</feetype> </subscriptioninfo> </reqbody> <reqbody> <oprnumb>210001bip2b518130410172224420909</oprnumb> <subscriptioninfo> <oprtime>oprtime2</oprtime> <actionid>actionid2</actionid> <brand>brand2</brand> <efftime>efftime2</efftime> <expiretime>expiretime2</expiretime> <feeuser_id>feeuserid2</feeuser_id> <destuser_id>destuserid2</destuser_id> <actionreasonid>actionid2</actionreasonid> <servtype>servtype2</servtype> <subservtype>subservtype2</subservtype> <spid>spid2</spid> <spservid>spservid2</spservid> <accessmode>accessmode2</accessmode> <servparaminfo> <para_num>0</para_num> <para_info> <para_name></para_name> <para_value></para_value> </para_info> </servparaminfo> <feetype>feetype2</feetype> </subscriptioninfo> </reqbody> </batchsyncorderrelationreq>]]></svccont> </interboss>
解码代码如下:
@xmlrootelement(name = "batchsyncorderrelationreq") @xmlaccessortype(xmlaccesstype.field) public class batchsyncorderrelationreq extends bossmessage<batchsyncorderrelationreq> { @xmlelement(name = "msgtransactionid") private string msgtransactionid = ""; @xmlelement(name = "reqnum") private string reqnum = ""; @xmlelement(name = "reqbody") private list<batchsyncorderrelationreqbody> reqbodylist; public batchsyncorderrelationreq() { } public string getmsgtransactionid() { return this.msgtransactionid; } public void setmsgtransactionid(string msgtransactionid) { this.msgtransactionid = msgtransactionid; } public string getreqnum() { return this.reqnum; } public void setreqnum(string reqnum) { this.reqnum = reqnum; } public list<batchsyncorderrelationreqbody> getreqbodylist() { return this.reqbodylist; } public void setreqbodylist(list<batchsyncorderrelationreqbody> reqbodylist) { this.reqbodylist = reqbodylist; } @override public batchsyncorderrelationreq deserialized(string interbossxmlcontent) throws businessexception { try { // deserialized for head jaxbcontext jaxbcxt4head = jaxbcontext.newinstance(messagehead.class); unmarshaller unmarshaller4head = jaxbcxt4head.createunmarshaller(); messagehead head = (messagehead) unmarshaller4head.unmarshal(new stringreader(interbossxmlcontent)); // deserialized for syncorderrelationreq body jaxbcontext jaxbcxt4body = jaxbcontext.newinstance(batchsyncorderrelationreq.class); unmarshaller unmarshaller4body = jaxbcxt4body.createunmarshaller(); batchsyncorderrelationreq batchsyncorderrelationreq = (batchsyncorderrelationreq) unmarshaller4body.unmarshal(new stringreader(head.getsvccont().trim())); batchsyncorderrelationreq.sethead(head); return batchsyncorderrelationreq; } catch (jaxbexception e) { throw new businessexception("syncorderrelationreq.deserialized() error!(" + interbossxmlcontent + ")", e); } } }
@xmlaccessortype(xmlaccesstype.field) public class batchsyncorderrelationreqbody { @xmlelement(name = "oprnumb") private string oprnumb = ""; @xmlelement(name = "subscriptioninfo") private subscriptioninfo subscriptioninfo; public batchsyncorderrelationreqbody(){ } public batchsyncorderrelationreqbody(string oprnumb, subscriptioninfo subscriptioninfo) { this.oprnumb = oprnumb; this.subscriptioninfo = subscriptioninfo; } public string getoprnumb() { return this.oprnumb; } public void setoprnumb(string oprnumb) { this.oprnumb = oprnumb; } public subscriptioninfo getsubscriptioninfo() { return this.subscriptioninfo; } public void setsubscriptioninfo(subscriptioninfo subscriptioninfo) { this.subscriptioninfo = subscriptioninfo; } }
@xmlaccessortype(xmlaccesstype.field) public class subscriptioninfo { @xmlelement(name = "oprtime") private string oprtime = ""; @xmlelement(name = "actionid") private string actionid = ""; @xmlelement(name = "brand") private string brand = ""; @xmlelement(name = "efftime") private string efftime = ""; @xmlelement(name = "expiretime") private string expiretime = ""; @xmlelement(name = "feeuser_id") private string feeuserid = ""; @xmlelement(name = "destuser_id") private string destuserid = ""; @xmlelement(name = "actionreasonid") private string actionreasonid = ""; @xmlelement(name = "servtype") private string servtype = ""; @xmlelement(name = "subservtype") private string subservtype = ""; @xmlelement(name = "spid") private string spid = ""; @xmlelement(name = "spservid") private string spservid = ""; @xmlelement(name = "accessmode") private string accessmode = ""; @xmlelement(name = "feetype") private string feetype = ""; public subscriptioninfo() { } public subscriptioninfo( string oprtime, string actionid, string brand, string efftime, string expiretime, string feeuserid, string destuserid, string actionreasonid, string servtype, string subservtype, string spid, string spservid, string accessmode, string feetype) { this.oprtime = oprtime; this.actionid = actionid; this.brand = brand; this.efftime = efftime; this.expiretime = expiretime; this.feeuserid = feeuserid; this.destuserid = destuserid; this.actionreasonid = actionreasonid; this.servtype = servtype; this.subservtype = subservtype; this.spid = spid; this.spservid = spservid; this.accessmode = accessmode; this.feetype = feetype; } public string getoprtime() { return this.oprtime; } public void setoprtime(string oprtime) { this.oprtime = oprtime; } public string getactionid() { return this.actionid; } public void setactionid(string actionid) { this.actionid = actionid; } public string getbrand() { return this.brand; } public void setbrand(string brand) { this.brand = brand; } public string getefftime() { return this.efftime; } public void setefftime(string efftime) { this.efftime = efftime; } public string getexpiretime() { return this.expiretime; } public void setexpiretime(string expiretime) { this.expiretime = expiretime; } public string getfeeuserid() { return this.feeuserid; } public void setfeeuserid(string feeuserid) { this.feeuserid = feeuserid; } public string getdestuserid() { return this.destuserid; } public void setdestuserid(string destuserid) { this.destuserid = destuserid; } public string getactionreasonid() { return this.actionreasonid; } public void setactionreasonid(string actionreasonid) { this.actionreasonid = actionreasonid; } public string getservtype() { return this.servtype; } public void setservtype(string servtype) { this.servtype = servtype; } public string getsubservtype() { return this.subservtype; } public void setsubservtype(string subservtype) { this.subservtype = subservtype; } public string getspid() { return this.spid; } public void setspid(string spid) { this.spid = spid; } public string getspservid() { return this.spservid; } public void setspservid(string spservid) { this.spservid = spservid; } public string getaccessmode() { return this.accessmode; } public void setaccessmode(string accessmode) { this.accessmode = accessmode; } public string getfeetype() { return this.feetype; } public void setfeetype(string feetype) { this.feetype = feetype; } }
更多java中对xml的解析详解。