使用XStream注解处理xml的属性及数据集合

相关jar包的Gradle设置

com.thoughtworks.xstream:xstream:1.4.8

xml的解析

一个看着比较“正常”的带有集合的xml

  1. carInfos做为根元素,其子元素是由N个carInfo组成的集合,每个carInfo元素描述一个对象信息。
  2. carInfo的子元素,每个tag做为属性名,tag所包含的txt做为属性值。
<carInfos dwName="sys.common.new_vehicle_DW">
	<carInfo index="1">
		<VehicleId>FTBAUD0088</VehicleId>
		<VehicleName>福克斯CAF7163B5轿车</VehicleName>
		<Remark>两厢 双离合 舒适型 国Ⅴ</Remark>
		<VehiclePrice>101800</VehiclePrice>
	</carInfo>
	<carInfo index="2">
		<VehicleId>FTBAUD0078</VehicleId>
		<VehicleName>福克斯CAF7163B5轿车</VehicleName>
		<Remark>两厢 双离合 风尚型 国Ⅴ</Remark>
		<VehiclePrice>113800</VehiclePrice>
	</carInfo>
	<carInfo index="3">
		<VehicleId>FTBAUD0097</VehicleId>
		<VehicleName>福克斯CAF7163B5轿车</VehicleName>
		<Remark>两厢 双离合 智行版 风尚型 国Ⅴ</Remark>
		<VehiclePrice>115800</VehiclePrice>
	</carInfo>
</carInfos>

与xml元素对应的Java类

对应carInfos元素

@XStreamAlias("carInfos")//对应carInfos元素
public class CarInfos {
	
	@XStreamAsAttribute
	private String dwName;//对应carInfos元素的dwName属性

	@XStreamImplicit(itemFieldName = "carInfo")
	private List<CarInfo> carInfoList = new ArrayList<CarInfo>();//对应N个carInfo元素组成的集合
    
    //省略getter/setter方法
}

对应carInfo元素

@XStreamAlias("carInfo")//对应carInfo元素
public class CarInfo {

	@XStreamAsAttribute
	private String index;//对应carInfo的index属性

	@XStreamAlias("VehicleId")
	private String vehicleId;//对应carInfo的VehicleId子元素

	@XStreamAlias("VehicleName")
	private String VehicleName;//对应carInfo的VehicleName子元素

	@XStreamAlias("Remark")
	private String remark;//对应carInfo的Remark子元素

	@XStreamAlias("VehiclePrice")
	private String vehiclePrice;//对应carInfo的VehiclePrice子元素
	
	//省略getter/setter方法
}

解析xml

public static void main(String[] args) throws Exception {
	File dataXml = readXml();//读取xml
	XStream xstream = new XStream(new DomDriver());//创建Xstram对象
	xstream.autodetectAnnotations(true);
	xstream.processAnnotations(CarInfos.class);
	CarInfos carInfos = (CarInfos) xstream.fromXML(dataXml);
	//打印对象
	System.out.printf("CarInfos dwName:%s\n", carInfos.getDwName());
	for (CarInfo carInfo : carInfos.getCarInfoList()) {
		System.out.printf("\tCarInfo index:%s\n", carInfo.getIndex());
		System.out.printf("\tCarInfo VehicleId:%s\n", carInfo.getVehicleId());
		System.out.printf("\tCarInfo VehicleName:%s\n", carInfo.getVehicleName());
		System.out.printf("\tCarInfo VehiclePrice:%s\n", carInfo.getVehiclePrice());
		System.out.printf("\tCarInfo Remark:%s\n", carInfo.getRemark());
	}
	//将对象转为xml,再次打印
	String resultXml = xstream.toXML(carInfos);
	System.out.printf("=======================\n" + resultXml);
}

不太一样的xml

一个“有点别扭”的xml

特点是carInfo元素下是多个attribute元素的集合。但是很明显,每个attribute元素的属性name的值,都本应该是carInfo元素的子元素的tagName。

<carInfos dwName="sys.common.new_vehicle_DW">
	<carInfo index="1">
		<attribute name="VehicleId">FTBAUD0088</attribute>
		<attribute name="VehicleName">福克斯CAF7163B5轿车</attribute>
		<attribute name="Remark">两厢 双离合 舒适型 国Ⅴ</attribute>
		<attribute name="VehiclePrice">101800</attribute>
	</carInfo>
	<carInfo index="2">
		<attribute name="VehicleId">FTBAUD0078</attribute>
		<attribute name="VehicleName">福克斯CAF7163B5轿车</attribute>
		<attribute name="Remark">两厢 双离合 风尚型 国Ⅴ</attribute>
		<attribute name="VehiclePrice">113800</attribute>
	</carInfo>
	<carInfo index="3">
		<attribute name="VehicleId">FTBAUD0097</attribute>
		<attribute name="VehicleName">福克斯CAF7163B5轿车</attribute>
		<attribute name="Remark">两厢 双离合 智行版 风尚型 国Ⅴ</attribute>
		<attribute name="VehiclePrice">115800</attribute>
	</carInfo>
</carInfos>

与xml元素对应的Java类

根据attribute元素,新建一个CarAttr类。

注意这里使用到@XStreamCoverter注解。 而且没有对成员变量添加注解。

@XStreamAlias("attribute")
@XStreamConverter(CarAttrConverter.class)
public class CarAttr {

    //没有使用@XStreamAsAttribute注解
	private String name;

    //没有使用注解
	private String value;
	
	//省略getter/setter方法
}

对CarInfo类进行修改,因为carInfo元素下是多个attribute元素,所以定义了一个List集合。如同CarInfos与CarInfo的关系。

@XStreamAlias("carInfo")
public class CarInfo {

	@XStreamAsAttribute
	private String index;

	@XStreamImplicit(itemFieldName = "attribute")
	private List<CarAttr> attrs = new ArrayList<CarAttr>();
	
	//省略getter/setter方法
}

定义CarAttr转换类

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;

public class CarAttrConverter implements Converter {

	@Override
	public boolean canConvert(Class type) {
		return type.equals(CarAttr.class);//转换条件
	}

	/**
	 * 将java对象转为xml时使用
	 */
	@Override
	public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
		CarAttr attr = (CarAttr) source;
		// writer.startNode("attribute");
		writer.addAttribute("name", attr.getName());
		writer.setValue(attr.getValue());
		// writer.endNode();
	}

	/**
	 * 将xml转为java对象使用
	 */
	@Override
	public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
		CarAttr a = new CarAttr();// 在解析attribute元素时,先创建一个CarAttr对象
		a.setName(reader.getAttribute("name"));// 将attribute元素的name属性设置为CarAttr对象的name属性值
		a.setValue(reader.getValue());// 将attribute元素的txt值设置为CarAttr对象的value值
		return a;
	}
}

解析xml

public static void main(String[] args) throws Exception {
		File dataXml = readXml();
		XStream xstream = new XStream(new DomDriver());
		xstream.autodetectAnnotations(true);
		xstream.processAnnotations(CarInfos.class);
		CarInfos carInfos = (CarInfos) xstream.fromXML(dataXml);
		//打印对象
		System.out.printf("CarInfos dwName:%s\n", carInfos.getDwName());
		for (CarInfo carInfo : carInfos.getCarInfoList()) {
			System.out.printf("\tCarInfo index:%s\n", carInfo.getIndex());
			for (CarAttr ca : carInfo.getAttrs()) {
				System.out.printf("\t\tCarAttr name:%s,value:%s\n", ca.getName(), ca.getValue());
			}
		}
		String resultXml = xstream.toXML(carInfos);
		System.out.printf("=======================\n" + resultXml);
	}

两个xml的解析方法没有区别,只是在打印解析出的对象时,稍有不同。 主要区别在于根据attribute元素,新增加了CarAttr类的定义,及与CarAttr类对应CarAttrConverter转换类的使用。

转载于:https://my.oschina.net/u/2610965/blog/886698

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值