天天看點

marshaller、unmarshaller解析xml及讀取xml

一、簡介:

本文主要介紹marshaller、unmarshaller的使用,并附上簡單的執行個體,DOM解析和SAX解析大家應該衆所周知,這裡就不介紹了,自行百度或檢視文檔即可,marshaller簡直就是神器,下面我們就來介紹一下。

首先,我們來介紹一下marshaller、unmarshaller有什麼用,及API的簡單介紹,JAXB(Java Architecture for XML Binding) 是一個業界的标準,是一項可以根據XML Schema産生Java類的技術。該過程中,JAXB也提供了對XML的執行個體文檔反向生成JAVA對象樹的方法,并能将Java對象樹的内容重新寫到XML執行個體文檔。從另一方面來講,JAXB提供了快速而簡便的方法将XML模式綁定到Java表示,進而使得Java開發者在Java應用程式中能友善地結合XML資料和處理函數。

marshaller :

從官網文檔來說,marshaller 類負責管理将Java内容樹序列化為XML資料的過程。簡單的來說可以把java對象序列話為轉為XML格式的資料。

Unmarshaller:

從官網文檔來說,Unmarshaller類管理将XML資料反序列化到新建立的Java内容樹中的過程,在未編組的情況下,還可以對XML資料進行驗證。簡單的來說。可以把XML格式的資料反序列化并且把資料綁定在Java bean的屬性上。

這裡我直接上案例,需要了解更多的可以移步官網文檔:marshaller unmarshaller

首先建立一個ReqHeader的類:

import javax.xml.bind.annotation.XmlElement;
public class ReqHeader {

    /** 系統編号*/
    private String sysId;

    /** 鑒權碼*/
    private String authCode;

    /** 流水号*/
    private String reqNo;

    public String getSysId() {
        return sysId;
    }
    @XmlElement(name = "SYSID")
    public void setSysId(String sysId) {
        this.sysId = sysId;
    }
    public String getAuthCode() {
        return authCode;
    }
    @XmlElement(name="AUTHCODE")
    public void setAuthCode(String authCode) {
        this.authCode = authCode;
    }
    public String getReqNo() {
        return reqNo;
    }
    @XmlElement(name="REQNO")
    public void setReqNo(String reqNo) {
        this.reqNo = reqNo;
    }
}
           

然後建立一個内容類:

public class SmsBody {
    /**
     * 短信内容
     */
    private String content;

    /**
     * 手機号
     */
    private String sourceAddr;
    
    /**
     * 服務代碼
     */
    private String destAddr;
    public String getContent() {
        return content;
    }

    @XmlElement(name = "CONTEXT")
    public void setContent(String content) {
        this.content = content;
    }

    public String getSourceAddr() {
        return sourceAddr;
    }

    @XmlElement(name = "SOURCEADDR")
    public void setSourceAddr(String sourceAddr) {
        this.sourceAddr = sourceAddr;
    }

    public String getDestAddr() {
        return destAddr;
    }

    @XmlElement(name="DESTADDR")
    public void setDestAddr(String destAddr) {
        this.destAddr = destAddr;
    }
}
           

最後建立一個包裝類:

@XmlRootElement(name = "SMSDELIVERREQ")
public class SmsDeliverReq {
    private ReqHeader reqHeader;
    private List<SmsBody> smsBodys;


    @XmlElement(name = "REQHEADER")
    public ReqHeader getReqHeader() {
        return reqHeader;
    }

    public void setReqHeader(ReqHeader reqHeader) {
        this.reqHeader = reqHeader;
    }

    /**
     * 在JAXB标準中,@XmlElementWrapper注解表示生成一個包裝 XML 表示形式的包裝器元素。
     * 此元素主要用于生成一個包裝集合的包裝器 XML 元素。是以,該注釋支援兩種形式的序列化。
     * @XmlElementWrapper 僅允許出現在集合屬性上
     * @return
     */
    @XmlElementWrapper(name = "SMSBODYS")
    @XmlElement(name = "SMSBODY")
    public List<SmsBody> getSmsBodys() {
        return smsBodys;
    }

    public void setSmsBodys(List<SmsBody> smsBodys) {
        this.smsBodys = smsBodys;
    }
}
           

測試代碼:

public class Test {

    /**
     * XML 轉轉為 JavaBean
     * @param xml
     * @param t
     * @param <T>
     * @return
     * @throws JAXBException
     */
    public static <T> T xmlToBean(String xml, T t) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        Unmarshaller um = context.createUnmarshaller();
        StringReader sr = new StringReader(xml);
        t = (T) um.unmarshal(sr);
        return t;
    }

    /**
     * JavaBean 轉換為 XML
     * @param t
     * @param <T>
     * @return
     * @throws JAXBException
     * @throws FileNotFoundException
     */
    public static <T> StringWriter beanToXml(T t) throws JAXBException, FileNotFoundException {
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        Marshaller m = context.createMarshaller();
        StringWriter sw = new StringWriter();
        m.marshal(t,sw);
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
        m.marshal(t,new FileOutputStream("/test.xml"));
        m.marshal(t,System.out);
        return sw;
    }
    public static void main(String[] args) throws JAXBException, FileNotFoundException {
        ReqHeader reqHeader = new ReqHeader();
        reqHeader.setReqNo("1");
        reqHeader.setAuthCode("AAA");
        reqHeader.setSysId("AAA123");

        SmsBody smsBody = new SmsBody();
        smsBody.setContent("測試1");
        smsBody.setDestAddr("15888");
        smsBody.setSourceAddr("888");

        SmsBody smsBody1 = new SmsBody();
        smsBody1.setContent("測試2");
        smsBody1.setDestAddr("159898");
        smsBody1.setSourceAddr("989898");

        SmsDeliverReq smsDeliverReq = new SmsDeliverReq();
        smsDeliverReq.setReqHeader(reqHeader);
        List<SmsBody> smsBodys = new ArrayList<SmsBody>();
        smsBodys.add(smsBody);
        smsBodys.add(smsBody1);
        smsDeliverReq.setSmsBodys(smsBodys);

        StringWriter sw = beanToXml(smsDeliverReq);
        System.out.println(sw.toString());

        SmsDeliverReq xmlToBean = xmlToBean(sw.toString(), smsDeliverReq);
        System.out.println(xmlToBean.getSmsBodys());

        System.out.println(xmlToBean.getSmsBodys().get(0).getContent());

    }
           

生成的xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SMSDELIVERREQ>
    <REQHEADER>
        <AUTHCODE>AAA</AUTHCODE>
        <REQNO>1</REQNO>
        <SYSID>AAA</SYSID>
    </REQHEADER>
    <SMSBODYS>
        <SMSBODY>
            <CONTEXT>測試1</CONTEXT>
            <DATE>2017-07-03T16:05:56.722+08:00</DATE>
            <DESTADDR>15888</DESTADDR>
            <SOURCEADDR>888</SOURCEADDR>
        </SMSBODY>
        <SMSBODY>
            <CONTEXT>測試2</CONTEXT>
            <DESTADDR>159898</DESTADDR>
            <SOURCEADDR>989898</SOURCEADDR>
        </SMSBODY>
    </SMSBODYS>
</SMSDELIVERREQ>
           

JDK中JAXB相關的重要Annotation: 

@XmlType,将Java類或枚舉類型映射到XML模式類型 

@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或屬性的序列化。FIELD表示JAXB将自動綁定Java類中的每個非靜态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值還有XmlAccessType.PROPERTY和XmlAccessType.NONE。 

@XmlAccessorOrder,控制JAXB 綁定類中屬性和字段的排序。 

@XmlJavaTypeAdapter,使用定制的擴充卡(即擴充抽象類XmlAdapter并覆寫marshal()和unmarshal()方法),以序列化Java類為XML。 

@XmlElementWrapper ,對于數組或集合(即包含多個元素的成員變量),生成一個包裝該數組或集合的XML元素(稱為包裝器)。 

@XmlRootElement,将Java類或枚舉類型映射到XML元素。 

@XmlElement,将Java類的一個屬性映射到與屬性同名的一個XML元素。 

@XmlAttribute,将Java類的一個屬性映射到與屬性同名的一個XML屬性。 

注意:序列化的java類的成員周遊不能聲明為public的,

注意:@XmlElementWrapper僅允許出現在集合屬性上。