使用XStream注解处理复杂xml的属性及数据集合(xml转对象) |
您所在的位置:网站首页 › xml的xmlns属性报错怎么修改 › 使用XStream注解处理复杂xml的属性及数据集合(xml转对象) |
1. XStream简介 2.简单使用 3.正常xml的解析 4.有点不正常xml的解析 5.更加不正常xml的解析 6.非常不正常xml的解析 1. XStream简介 XStream是一个Java对象与XML互相转换的工具类库。 官网链接: http://x-stream.github.io/index.html 2.简单使用 下载页面:http://x-stream.github.io/download.html 使用Maven构建项目的加入以下依赖: com.thoughtworks.xstream xstream 1.4.10 org.projectlombok lombok ${lombok.version} 12345678910 3.正常xml的解析 注意:代码中xmlString都代表当前小结里面的xml字符串 lanweihong [email protected] 1234 对象 public class User { private String userName; private String email; public User(String userName, String email) { this.userName = userName; this.email = email; } }12345678910 运行 public static void main(String[] args) { XStream xStream = new XStream(); xStream.alias("User", User.class); String xml = xmlString; //转对象 User user = (User)xStream.fromXML(xml); System.out.println(user.toString()); }12345678 输出文本为: User:{userName=lanweihong,[email protected]}1 4.有点不正常xml的解析 一个看着比较“正常”的带有集合的xml 1. carInfos做为根元素,其子元素是由N个carInfo组成的集合,每个carInfo元素描述一个对象信息。 2. carInfo的子元素,每个tag做为属性名,tag所包含的txt做为属性值。 FTBAUD0088 福克斯CAF7163B5轿车 两厢 双离合 舒适型 国Ⅴ 101800 FTBAUD0078 福克斯CAF7163B5轿车 两厢 双离合 风尚型 国Ⅴ 113800 FTBAUD0097 福克斯CAF7163B5轿车 两厢 双离合 智行版 风尚型 国Ⅴ 115800 1234567891011121314151617181920 与xml元素对应的Java类 对应carInfos元素 @XStreamAlias("carInfos")//对应carInfos元素 public class CarInfos { @XStreamAsAttribute private String dwName;//对应carInfos元素的dwName属性 @XStreamImplicit(itemFieldName = "carInfo") private List carInfoList = new ArrayList();//对应N个carInfo元素组成的集合 //省略getter/setter方法 }1234567891011 对应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方法 }1234567891011121314151617181920 解析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); }12345678910111213141516171819 5.更加不正常xml的解析 一个“有点别扭”的xml 特点是carInfo元素下是多个attribute元素的集合。但是很明显,每个attribute元素的属性name的值,都本应该是carInfo元素的子元素的tagName。 FTBAUD0088 福克斯CAF7163B5轿车 两厢 双离合 舒适型 国Ⅴ 101800 FTBAUD0078 福克斯CAF7163B5轿车 两厢 双离合 风尚型 国Ⅴ 113800 FTBAUD0097 福克斯CAF7163B5轿车 两厢 双离合 智行版 风尚型 国Ⅴ 115800 1234567891011121314151617181920 与xml元素对应的Java类 根据attribute元素,新建一个CarAttr类。 注意这里使用到@XStreamCoverter注解。 而且没有对成员变量添加注解。 @XStreamAlias("attribute") @XStreamConverter(CarAttrConverter.class) public class CarAttr { //没有使用@XStreamAsAttribute注解 private String name; //没有使用注解 private String value; //省略getter/setter方法 }123456789101112 对CarInfo类进行修改,因为carInfo元素下是多个attribute元素,所以定义了一个List集合。如同CarInfos与CarInfo的关系。 @XStreamAlias("carInfo") public class CarInfo { @XStreamAsAttribute private String index; @XStreamImplicit(itemFieldName = "attribute") private List attrs = new ArrayList(); //省略getter/setter方法 }1234567891011 定义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; } }123456789101112131415161718192021222324252627282930313233343536 解析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); }1234567891011121314151617 两个xml的解析方法没有区别,只是在打印解析出的对象时,稍有不同。主要区别在于根据attribute元素,新增加了CarAttr类的定义,及与CarAttr类对应CarAttrConverter转换类的使用。 6.非常不正常xml的解析 123456789101112131415161718 这里有俩坑 1. 坑1:dlineage对象我的Dlinage(一个解析血缘的工具类收费的))已经存储,不能定义这个 2. 坑2:parent_id parent_name 不识别带有横岗的属性 针对这两个问题对xml进行预处理 xmlString = xmlString.replaceAll("dlineage","DlineageEntity"); xmlString = xmlString.replaceAll("parent_id","parentId"); xmlString = xmlString.replaceAll("parent_name","parentName");123 建立实体类 @Data @XStreamAlias("DlineageEntity")//对应dlineage元素 public class DlineageEntity { // 对应relation @XStreamImplicit(itemFieldName = "relation") private List relation; // 对应table @XStreamImplicit(itemFieldName = "table") private List table; } 1234567891011121314 @Data @XStreamAlias("relation") // 对应relation public class Relation { // 对应 id 属性 @XStreamAsAttribute private String id; // 对应 type 属性 @XStreamAsAttribute private String type; // 对应 target 子元素 @XStreamImplicit(itemFieldName = "target") private List target ; // 对应 source 子元素 @XStreamImplicit(itemFieldName = "source") private List source ; } 1234567891011121314151617181920 @Data @XStreamAlias("target") // 对应 target public class Target { // 对应 coordinate 属性 @XStreamAsAttribute private String coordinate; // 对应 column 属性 @XStreamAsAttribute private String column; // 对应 id 属性 @XStreamAsAttribute private String id; // 对应 parentId 属性 @XStreamAsAttribute private String parentId; // 对应 parentName 属性 @XStreamAsAttribute private String parentName; }123456789101112131415161718192021 @Data @XStreamAlias("source") public class Source { @XStreamAsAttribute private String coordinate; @XStreamAsAttribute private String column; @XStreamAsAttribute private String id; @XStreamAsAttribute private String parentId; @XStreamAsAttribute private String parentName; }12345678910111213141516 @Data @XStreamAlias("table") public class Table { @XStreamAsAttribute private String name; @XStreamAsAttribute private String id; @XStreamAsAttribute private String type; @XStreamAsAttribute private String coordinate; @XStreamImplicit(itemFieldName = "column") private List column; } 1234567891011121314151617 @Data @XStreamAlias("column") public class Column { @XStreamAsAttribute private String name; @XStreamAsAttribute private String id; @XStreamAsAttribute private String coordinate; } 1234567891011121314 解析对象 private static void makeBlood(String result ) { result = result.replaceAll("dlineage","DlineageEntity"); result = result.replaceAll("parent_id","parentId"); result = result.replaceAll("parent_name","parentName"); System.out.println( "===>"+result ); XStream xStream = new XStream(); xStream.autodetectAnnotations(true); xStream.processAnnotations(DlineageEntity.class); DlineageEntity carInfos = (DlineageEntity) xStream.fromXML(result); System.out.println(carInfos.toString()); }1234567891011121314 结果 DlineageEntity( relation=[ Relation( id=3, type=dataflow, target=[ Target( coordinate=[1,27],[1,31], column=NAME, id=5, parentId=1, parentName=TABLEA)], source=[Source(coordinate=[1,27],[1,31], column=NAME, id=1, parentId=2, parentName=B)] ), Relation(id=4, type=dataflow, target=[Target(coordinate=[1,32],[1,35], column=AGE, id=6, parentId=1, parentName=TABLEA)], source=[Source(coordinate=[1,32],[1,35], column=AGE, id=2, parentId=2, parentName=B)] ) ], table=[ Table(name=TABLEA, id=1, type=table, coordinate=[1,13],[1,19], column=[ Column(name=NAME, id=5, coordinate=[1,27],[1,31]), Column(name=AGE, id=6, coordinate=[1,32],[1,35]) ] ), Table(name=B, id=2, type=table, coordinate=[1,42],[1,43], column=[ Column(name=NAME, id=1, coordinate=[1,27],[1,31]), Column(name=AGE, id=2, coordinate=[1,32],[1,35]) ] ) ) 123456789101112131415161718192021222324252627 --------------------- 作者:九师兄-梁川川 来源:CSDN 原文:https://blog.csdn.net/qq_21383435/article/details/82116706 版权声明:本文为博主原创文章,转载请附上博文链接! |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |