随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

简介

java自带的jar包中并不支持Javabean和xml的转换

所以是首先要使用的两个jar包:

Javabean和xml的转换是XStream中的类和方法,而使用XStream就必须依赖xpp3jar包;

XStream网上都能下载,下面是下载xpp3的网址,但是原网址被废弃了,存档一般是进不去的

http://www.extreme.indiana.edu/xgws/xsoap/xpp/

百度上搜了下,很多下载xpp3都要收费的,这里作为学习交流提供XStream和xpp3的jar包:

链接:https://pan.baidu.com/s/1PYfE3yiYdXEHVFUeaa6SSw?pwd=8080
提取码:8080

 

然后就是创建java工程和导入jar包了,导包可以参照:

https://www.cnblogs.com/0099-ymsml/p/16062244.html

 

应用:

javabean和xml的转换需要使用toXml()方法:

 

public String toXML(Object obj) {
        Writer writer = new StringWriter();
        toXML(obj, writer);
        return writer.toString();
    }

 

 

public void toXML(Object obj, Writer out) {
        HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out);
        try {
            marshal(obj, writer);
        } finally {
            writer.flush();
        }
    }

 

 

public void marshal(Object obj, HierarchicalStreamWriter writer) {
        marshal(obj, writer, null);
    }

 

public void marshal(Object obj, HierarchicalStreamWriter writer, DataHolder dataHolder) {
        marshallingStrategy.marshal(writer, obj, converterLookup, mapper, dataHolder);
    }

上面就是XStream中的toXml()方法,

太多了懒得分析,返回的是一个xml形式的字符串。

使用toXml():

首先需要创建标准Java类:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author CDU_LM
 * 省份类
 */
public class Province {
    private String name;     // 名称
    private List<City> cities = new ArrayList<City>();
    
    public Province(String name, List<City> cities) {
        this.name = name;
        this.cities = cities;
    }

    public Province() {
        // TODO Auto-generated constructor stub
    }
    public String getName() {
        return name;
    }

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

    public List<City> getCities() {
        return cities;
    }

    public void setCities(List<City> cities) {
        this.cities = cities;
    }

    @Override
    public int hashCode() {
        return Objects.hash(cities, name);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Province other = (Province) obj;
        return Objects.equals(cities, other.cities) && Objects.equals(name, other.name);
    }

    @Override
    public String toString() {
        return "Province [name=" + name + ", cities=" + cities + "]";
    }
    public void addCity(City city) {
        this.cities.add(city);
    }
}

 

import java.util.Objects;

// 城市类
public class City {
    private String name;    // 名称
    private String descript;    // 描述
    public City(String name, String descript) {
        this.name = name;
        this.descript = descript;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescript() {
        return descript;
    }
    public void setDescript(String descript) {
        this.descript = descript;
    }
    @Override
    public int hashCode() {
        return Objects.hash(descript, name);
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        City other = (City) obj;
        return Objects.equals(descript, other.descript) && Objects.equals(name, other.name);
    }
    @Override
    public String toString() {
        return "Province [name=" + name + ", descript=" + descript + "]";
    }
}

然后是创建一个@Test测试类:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;

// 测试类
public class JavaToXml {
    // 返回javabean集合
    public List<Province> getProvinceList(){
        Province p1 = new Province();    // 创建省1
        p1.setName("北京");    // 省份名称
        p1.addCity(new City("东城区","dcq"));    // 添加城市
        p1.addCity(new City("西城区","xcq"));    // 添加城市
        p1.addCity(new City("北城区","bcq"));    // 添加城市
        
        Province p2 = new Province();    // 创建省2
        p2.setName("四川");    // 省份名称
        p2.addCity(new City("简阳","jy"));    // 添加城市
        p2.addCity(new City("成都","cd"));    // 添加城市
        p2.addCity(new City("绵阳","my"));    // 添加城市
        
        List<Province> provinceList = new ArrayList<>();    // 创建集合
        provinceList.add(p1);    // 添加元素p1
        provinceList.add(p2);    // 添加元素p2
        
        return provinceList;
    }
    @SuppressWarnings("resource")
    @Test
    public void fun1() {
        List<Province> proList = getProvinceList();
        /**
         * 创建XStream对象
         * 调用toXML()方法把集合转换为字符串
         */
        XStream xs = new XStream();
        String s = "<?xml version='1.0' encoding='utf-8'?>\n";
        s +=xs.toXML(proList);
        System.out.print(s);
        try {
            PrintStream print = new PrintStream("D:" + File.separator + "toXml.xml");
            print.print(s);
            print.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

运行这个测试类:

 

<?xml version='1.0' encoding='utf-8'?>
<list>
  <toXml.Province>
    <name>北京</name>
    <cities>
      <toXml.City>
        <name>东城区</name>
        <descript>dcq</descript>
      </toXml.City>
      <toXml.City>
        <name>西城区</name>
        <descript>xcq</descript>
      </toXml.City>
      <toXml.City>
        <name>北城区</name>
        <descript>bcq</descript>
      </toXml.City>
    </cities>
  </toXml.Province>
  <toXml.Province>
    <name>四川</name>
    <cities>
      <toXml.City>
        <name>简阳</name>
        <descript>jy</descript>
      </toXml.City>
      <toXml.City>
        <name>成都</name>
        <descript>cd</descript>
      </toXml.City>
      <toXml.City>
        <name>绵阳</name>
        <descript>my</descript>
      </toXml.City>
    </cities>
  </toXml.Province>
</list>

可以发现这个运行结果去掉第一行人为添加的后:

根元素<list>:使用的List接口集合类型,如果是使用其它的集合类型就是对应的类型名称

下面的<toXml.Province>:包.省份类名

<toXml.Province>下面的<name>:Province 的第一个成员属性

<toXml.Province>下面的<cities>:Province 的第二个成员属性

<toXml.City> :包.城市类名

<toXml.City> 下面的<name>:City的第一个成员属性

<toXml.City> 下面的<descript>:City的第二个成员属性

那么结构就是这样了,成功地将Java类转换为了xml的形式。

然后在文件路径中有:

 

 

打开后:

 

如果打开报错,可能是编码的问题,可以在:

 

 

 

 

选择utf-8,建议写代码之前就换一下,因为默认的是gbk格式,在转换为utf-8后会导致中文乱码;

 

在程序开发中建议的也是utf-8格式。

 

给默认的标签起别名:

上面我们发现 得出结果的xml数据的标签是根据包和类来定义的,看着很不规律或整齐,所以可以使用XStream中的alias()方法

 首先看看alias()方法的代码:

classAliasingMapper 是 类别名映射器

public void alias(String name, Class type) {
        if (classAliasingMapper == null) {
            throw new com.thoughtworks.xstream.InitializationException("No "
                + ClassAliasingMapper.class.getName()
                + " available");
        }
        classAliasingMapper.addClassAlias(name, type);
    }

 如果classAliasingMapper 不为空,那么就执行addClassAlias()方法

public void addClassAlias(String name, Class type) {
        nameToType.put(name, type.getName());
        classToName.put(type.getName(), name);
    }

addClassAlias()方法中可以发现,和Map集合有了联系。

private final Map classToName = new HashMap();
private transient Map nameToType = new HashMap()
put()方法就相当于在给classToName和nameToType赋值

想要深究的可以去看源码

@Test
    public void fun2() {
        List<Province> proList = getProvinceList();
        XStream xs = new XStream();
        
        xs.alias("china", List.class);            // List类型别名为china
        xs.alias("province", Province.class);    // Province类型别名为province
        xs.alias("city", City.class);            // City类型别名为city
        
        String s = "<?xml version='1.0' encoding='utf-8'?>\n";
        s +=xs.toXML(proList);
        System.out.print(s);
    }

 运行结果:

<?xml version='1.0' encoding='utf-8'?>
<china>
  <province>
    <name>北京</name>
    <cities>
      <city>
        <name>东城区</name>
        <descript>dcq</descript>
      </city>
      <city>
        <name>西城区</name>
        <descript>xcq</descript>
      </city>
      <city>
        <name>北城区</name>
        <descript>bcq</descript>
      </city>
    </cities>
  </province>
  <province>
    <name>四川</name>
    <cities>
      <city>
        <name>简阳</name>
        <descript>jy</descript>
      </city>
      <city>
        <name>成都</name>
        <descript>cd</descript>
      </city>
      <city>
        <name>绵阳</name>
        <descript>my</descript>
      </city>
    </cities>
  </province>
</china>

这样就可以使对应的标签变成自定义标签名称;

 

将某个类的成员属性变为xml中标签的属性:

/**
     * 默认子元素是java类的成员属性
     * 现在需要将某些java类的成员属性变为标签的属性
     */
    @Test
    public void fun3() {
        List<Province> proList = getProvinceList();
        XStream xs = new XStream();
        xs.alias("china", List.class);            // List类型别名为china
        xs.alias("province", Province.class);    // Province类型别名为province
        xs.alias("city", City.class);            // City类型别名为city
        
        /**
         * 把Pprovince类型的name属性变为<province>标签的属性
         */
        xs.useAttributeFor(Province.class,"name");    // 将Province类的name成员属性变为xml中的标签属性
        
        
        String s = "<?xml version='1.0' encoding='utf-8'?>\n";
        s +=xs.toXML(proList);
        System.out.print(s);
    }

运行结果:

</china><?xml version='1.0' encoding='utf-8'?>
<china>
  <province name="北京">
    <cities>
      <city>
        <name>东城区</name>
        <descript>dcq</descript>
      </city>
      <city>
        <name>西城区</name>
        <descript>xcq</descript>
      </city>
      <city>
        <name>北城区</name>
        <descript>bcq</descript>
      </city>
    </cities>
  </province>
  <province name="四川">
    <cities>
      <city>
        <name>简阳</name>
        <descript>jy</descript>
      </city>
      <city>
        <name>成都</name>
        <descript>cd</descript>
      </city>
      <city>
        <name>绵阳</name>
        <descript>my</descript>
      </city>
    </cities>
  </province>

可以发现Province类下的name成员属性变为了标签<province>中的属性

 

 

使某个类中的某个成员属性不显示在xml的标签中:

换一种说法就是只是将集合中(不包括集合名本身)的元素生成xml标签

@Test
    public void fun4() {
        List<Province> proList = getProvinceList();
        XStream xs = new XStream();
        xs.alias("china", List.class);            // List类型别名为china
        xs.alias("province", Province.class);    // Province类型别名为province
        xs.alias("city", City.class);            // City类型别名为city
        xs.useAttributeFor(Province.class,"name");    // 将Province类的name成员属性变为xml中的标签属性
        
        /**
         * 去掉<cities>这样的集合类型属性
         */
        xs.addImplicitCollection(Province.class, "cities");    // 使Province类中的cities不显示在xml标签中
        
        
        String s = "<?xml version='1.0' encoding='utf-8'?>\n";
        s +=xs.toXML(proList);
        System.out.print(s);
    }

运行结果:

<?xml version='1.0' encoding='utf-8'?>
<china>
  <province name="北京">
    <city>
      <name>东城区</name>
      <descript>dcq</descript>
    </city>
    <city>
      <name>西城区</name>
      <descript>xcq</descript>
    </city>
    <city>
      <name>北城区</name>
      <descript>bcq</descript>
    </city>
  </province>
  <province name="四川">
    <city>
      <name>简阳</name>
      <descript>jy</descript>
    </city>
    <city>
      <name>成都</name>
      <descript>cd</descript>
    </city>
    <city>
      <name>绵阳</name>
      <descript>my</descript>
    </city>
  </province>
</china>

上面的xml就去掉了<cities>这个标签。

 

使用某些javabean属性不生成为xml标签:

@Test
    public void fun5() {
        List<Province> proList = getProvinceList();
        XStream xs = new XStream();
        xs.alias("china", List.class);            // List类型别名为china
        xs.alias("province", Province.class);    // Province类型别名为province
        xs.alias("city", City.class);            // City类型别名为city
        xs.useAttributeFor(Province.class,"name");    // 将Province类的name成员属性变为xml中的标签属性
        xs.addImplicitCollection(Province.class, "cities");    // 使Province类中的cities不显示在xml标签中
        
        /**
         * 使某些类的某个属性不生成对应的xml标签
         */
        xs.omitField(City.class,"descript");
        
        String s = "\n<?xml version='1.0' encoding='utf-8'?>\n";
        s +=xs.toXML(proList);
        System.out.print(s);
    }

运行结果:

<?xml version='1.0' encoding='utf-8'?>
<china>
  <province name="北京">
    <city>
      <name>东城区</name>
    </city>
    <city>
      <name>西城区</name>
    </city>
    <city>
      <name>北城区</name>
    </city>
  </province>
  <province name="四川">
    <city>
      <name>简阳</name>
    </city>
    <city>
      <name>成都</name>
    </city>
    <city>
      <name>绵阳</name>
    </city>
  </province>
</china>

 这样xml中的<descript>标签就不会生成了

 

posted on 2022-04-03 11:02  时间完全不够用啊  阅读(1626)  评论(0编辑  收藏  举报