天天看點

Android XStream解析XML

一、資源下載下傳

XStream      XStream.jar

二、注解

@XStreamAlias 

 java對象在xml中以标簽的形式顯示時,如果名字與類名或者屬性名不一緻,可以使用該标簽并在括号内注明别名

 @XStreamOmitField

在輸出XML的時候忽略該屬性 

@XStreamImplicit 

如果該屬性是一個清單或者數組,在XML中不顯示list或者Array字樣 

@XStreamAsAttribute

該屬性不單獨顯示成XML節點,而是作為屬性顯示出來 

@XStreamConverter 

設定轉換器 

@XStreamConverters

converter主要用于将某些字段進行複雜的轉換,轉換過程寫在一個類中。然後将其注冊到XStream

三、執行個體

1.xml檔案

<movie>
    <code>200</code>
    <performerlist>
        <performer name="tony" age="49"/>
        <performer name="andy" age="50"/>
    </performerlist>
    <information>
        <title>Infernal Affairs</title>
        <year>2002</year>
        <film_review organization="times" film_score="95">perfect movie</film_review>
    </information>
</movie>
           

2.bean類

package com.xml.xstream;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamImplicit;

import java.util.List;

/**
 * Created by askilledhand on 2021/1/27
 */
@XStreamAlias("movie")
public class ResultBean {

    public String code;
    public PerformerList performerlist;
    public Information information;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public PerformerList getPerformerList() {
        return performerlist;
    }

    public void setPerformerList(PerformerList performerlist) {
        this.performerlist = performerlist;
    }

    public Information getInfomation() {
        return information;
    }

    public void setInfomation(Information information) {
        this.information = information;
    }

    @XStreamAlias("performerlist")
    public static class PerformerList {

        @XStreamImplicit(itemFieldName = "performer") // 節點注解
        public List<Performer> performers;

        public List<Performer> getList() {
            return performers;
        }

        public void setList(List<Performer> performers) {
            this.performers = performers;
        }

        @XStreamAlias("performer")
        public static class Performer {
            @XStreamAsAttribute() @XStreamAlias("name") // 屬性注解
            private String name;
            @XStreamAsAttribute() @XStreamAlias("age") // 屬性注解
            private String age;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public String getAge() {
                return age;
            }

            public void setAge(String age) {
                this.age = age;
            }
        }
    }

    @XStreamAlias("information")
    public static class Information {
        private String title;
        private String year;
        @XStreamAlias("film_review") // 變量名用film_review的話,就可以不用注解
        public FilmReview filmReview;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }

        public FilmReview getFilmReview() {
            return filmReview;
        }

        public void setFilmReview(FilmReview filmReview) {
            this.filmReview = filmReview;
        }

        @XStreamAlias("film_review")
        @XStreamConverter(FilmReviewConverter.class)
        public static class FilmReview {
            public String value;
            public String organization;
            public String film_score;

            public String getValue() {
                return value;
            }

            public void setValue(String value) {
                this.value = value;
            }

            public String getOrganization() {
                return organization;
            }

            public void setOrganization(String organization) {
                this.organization = organization;
            }

            public String getFilm_score() {
                return film_score;
            }

            public void setFilm_score(String film_score) {
                this.film_score = film_score;
            }

        }
    }
}
           

3.轉換器(節點既有屬性又有值)

package com.xml.xstream;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

/**
 * Created by askilledhand on 2021/1/27
 */
public class FilmReviewConverter implements Converter {

    /**
     * 将java對象轉為xml時使用
     */
    @Override
    public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
        ResultBean.Information.FilmReview filmReview = (ResultBean.Information.FilmReview) o;
        hierarchicalStreamWriter.addAttribute("organization", filmReview.getOrganization());
        hierarchicalStreamWriter.addAttribute("film_score", filmReview.getFilm_score());
        hierarchicalStreamWriter.setValue(filmReview.getValue());
    }

    /**
     * 将xml轉為java對象使用
     */
    @Override
    public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
        ResultBean.Information.FilmReview filmReview = new ResultBean.Information.FilmReview();
        //代碼順序必須先getAttribute,然後再getValue,切記
        filmReview.setOrganization(hierarchicalStreamReader.getAttribute("organization"));
        filmReview.setFilm_score(hierarchicalStreamReader.getAttribute("film_score"));
        filmReview.setValue(hierarchicalStreamReader.getValue());
        return filmReview;
    }

    @Override
    public boolean canConvert(Class aClass) {
        return aClass.equals(ResultBean.Information.FilmReview.class);
    }
}
           

4.解析

public static <T> T parseXML(Class<T> clazz, String str) {
    DomDriver domDriver = new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"));
    XStream xStream = new XStream(domDriver);
    xStream.processAnnotations(clazz);
    T bean = (T) xStream.fromXML(new ByteArrayInputStream(str.getBytes()));
    return bean;
}
           

四、注意事項

1.xml裡有的節點,bean類裡一定要有;

2.屬性名如果和xml節點名稱不一樣,就需要使用@XStreamAlias注解,否則會報No such field錯;

3.節點屬性名包含下劃線時,會解析不到該節點,可以用以下方式初始化XStream:

DomDriver domDriver = new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"));
XStream xStream = new XStream(domDriver);
           

FINALLY:以上代碼實測能正常解析,使用的xstream-1.4.7.jar