欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java中对XML的解析详解

程序员文章站 2023-12-17 08:31:28
先简单说下前三种方式: dom方式:个人理解类似.net的xmldocument,解析的时候效率不高,占用内存,不适合大xml的解析; sax方式:基于事件的解析,当解...

先简单说下前三种方式:

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;
    }
}

上一篇:

下一篇: