使用XStream注解处理复杂xml的属性及数据集合(xml转对象)

您所在的位置:网站首页 xml的xmlns属性报错怎么修改 使用XStream注解处理复杂xml的属性及数据集合(xml转对象)

使用XStream注解处理复杂xml的属性及数据集合(xml转对象)

2024-07-17 14:36| 来源: 网络整理| 查看: 265

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