依赖开源库XStream ,需要用到java注解
Talk is cheap,直接看代码
测试用xml数据结构
<?xml version="1.0" encoding="UTF-8"?>
<feed>
<title>测试</title>
<entry>
<id>52231366</id>
<published>2017-06-27T16:16:18.000Z</published>
<title type="text">深夜剧场:彝海结盟 18</title>
<content type="text">
1935年5月遵义会议后,在毛泽东的指挥下,中央红军四渡赤水、两占遵义、佯攻贵阳、进逼昆明,甩开了川滇黔湘桂的国民党30万大军的围追堵截。
</content>
<media:group>
<itv:cid>52231366</itv:cid>
<itv:code>02000006000000072017062680000002</itv:code>
<itv:attribute name="start">20170627011600</itv:attribute>
<itv:attribute name="runtime">00:14:00</itv:attribute>
</media:group>
<itv:itv/>
</entry>
<entry>
<id>52231367</id>
<published>2017-06-27T16:16:18.000Z</published>
<title type="text">深夜剧场:彝海结盟</title>
<content type="text">
1935年5月遵义会议后,在毛泽东的指挥下,中央红军四渡赤水、两占遵义、佯攻贵阳、进逼昆明,甩开了川滇黔湘桂的国民党30万大军的围追堵截。
</content>
<media:group>
<itv:cid>52231367</itv:cid>
<itv:attribute name="start">20170627013000</itv:attribute>
<itv:attribute name="runtime">03:24:00</itv:attribute>
</media:group>
<itv:itv/>
</entry>
</feed>
根据数据结构定义javabean
Feed.java
@XStreamAlias("feed")
public class Feed {
@XStreamImplicit
public List<Entry> entries;
}
@XStreamImplicit的作用,如果不加此注解则匹配数据结构如下:
<feed> <entrys> <entry/> <entry/> </entrys> </feed>
Entry.java
@XStreamAlias("entry")
public class Entry {
public String id;
public String published;
public String title;
public String content;
@XStreamAlias("media:group")
public MediaGroup mediaGroup;
}
MedieGroup.java
@XStreamAlias("media:group")
public class MediaGroup {
@XStreamAlias("itv:cid")
public String itvCid;
@XStreamImplicit
public List<ItvAttribute> itvAttributes;
@XStreamAlias("itv:attribute")
@XStreamConverter(ItvAttriConverter.class) // 在注解中指定转换器
public static class ItvAttribute{
@XStreamAsAttribute
public String name;
public String text;
}
}
@XStreamAsAttribute表示成员变量是属性元素,如下“name”
<feed> <entry> <media:group> <itv:attribute name="n">v</itv:attribute> <itv:attribute name="n">v</itv:attribute> </media:group> </entry> </feed>
ItvAttriConverter .java
public class ItvAttriConverter implements Converter {
// 序列化时执行
@Override
public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
MediaGroup.ItvAttribute itvAttribute = (MediaGroup.ItvAttribute) o;
if (itvAttribute.name != null) {
hierarchicalStreamWriter.addAttribute("name", itvAttribute.name);
}
if (itvAttribute.text != null) {
hierarchicalStreamWriter.setValue(itvAttribute.text);
}
}
// 反序列化时执行
@Override
public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
MediaGroup.ItvAttribute itvAttribute = new MediaGroup.ItvAttribute();
itvAttribute.name = hierarchicalStreamReader.getAttribute("name"); //得到属性的值
itvAttribute.text = hierarchicalStreamReader.getValue(); //得到<itv:attribute/>节点的值
return itvAttribute;
}
@Override
public boolean canConvert(Class aClass) {
return aClass.equals(MediaGroup.ItvAttribute.class);
}
}
封装:
public class XmlParser {
private XStream xStream;
public XmlParser(){
xStream = new XStream(new Xpp3Driver());
xStream.ignoreUnknownElements(); // 忽略javabean中没有定义但在xml中存在的元素,不加这句会报错
xStream.processAnnotations(Feed.class);
}
public Feed parse(String xml) {
Feed feed = (Feed) xStream.fromXML(xml);
return feed;
}
public String toXml(Object obj) {
return xStream.toXML(obj);
}
}
Test:
public static void main(String[] args){
// 序列化
Feed feed = new Feed();
List<Entry> entries = new ArrayList<Entry>();
Entry entry = new Entry();
entry.mediaGroup = new MediaGroup();
entry.mediaGroup.itvAttributes = new ArrayList<MediaGroup.ItvAttribute>();
entry.mediaGroup.itvAttributes.add(new MediaGroup.ItvAttribute());
entries.add(entry);
feed.entries = entries;
String xx = new XmlParser().toXml(feed);
System.out.println(xx);
// 反序列化
Feed fd = new XmlParser().parse(xx);
}
PS:但我们需要对某个xml数据进行反序列化时,调试时可以优先测试序列化得到的xml是否给出的xml数据结构一致。