Java下3中XML解析 DOM方式、SAX方式和StAX方式

2022-10-20,,,

先简单说下前三种方式

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下3中XML解析 DOM方式、SAX方式和StAX方式.doc》

下载本文的Word格式文档,以方便收藏与打印。