java使用xstream实现xml文件和对象之间的相互转换

java使用xstream实现xml文件和对象之间的相互转换

  • 整体描述
  • 具体实现
    • 1. 引入xstream的maven
    • 2.xml文件
    • 3. 创建相应的对象
    • 4. 创建xml工具类
    • 5. 创建读取/写入文件工具类
    • 5. xml和对象的转换
  • 结语

整体描述

xml是一个用途比较广泛的文件类型,在java里也自带解析xml的包,但是本文使用的是xstream来实现xml和对象之间的相互转换,xstream是一个第三方开源框架,使用起来比较方便,xstream官网地址: xstream官网,目前最新版本是1.4.19。

具体实现

1. 引入xstream的maven

添加xstream的依赖,这里使用最新的1.4.19版本

        
            com.thoughtworks.xstream
            xstream
            1.4.19
        

2.xml文件

这里使用的是大疆无人机的地图文件template.kml :
xml文件参考文档:大疆云上API地址: 大疆云上API。
文件具体格式如下,基本包含了xml所有需要使用的示例。
注:文件虽然是.kml格式,但其实就是xml的格式。





  
  Name
  1637600807044
  1637600875837
 
  
  
    safely
    goHome
    goContinue
    20
    10
    
      
      67
      0
    
    
      
      52
      0
      0
    
  
 
  
  
    waypoint
    0
    0
    
      WGS84
      EGM96
      100
      100
      GPS
    
    7
    7
    usePointSetting
    
      followWayline
    
    toPointAndStopWithDiscontinuityCurvature
    
      
        
        
          longitude,latitude
        
      
      0
      90.2
      100
      1
      1
      1
      1
      0
    
    
      
        
        
          longitude,latitude
        
      
      1
      90.2
      100
      1
      1
      1
      1
      0
      
      
        0
        1
        1
        sequence
        
          reachPoint
        
        
        
          0
          gimbalRotate
          
            absoluteAngle
            0
            0
            0
            0
            1
            30
            0
            0
            0
          
        
        
        
          1
          takePhoto
          
            point1
            0
          
        
      
    
  
 


3. 创建相应的对象

根据xml文件的格式,创建出各个节点的对象,使用xstream的注解实现设置标签的功能,这里主要使用以下几个注解:
@XStreamAlias(“kml”):设置标签,内容为对象;
@XStreamImplicit(itemFieldName = “Placemark”):设置标签,内容为list
@XStreamAsAttribute:标签内属性
具体对象类:
最外层的Kml对象:

package com.thcb.xml.bean.template;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import lombok.Data;

/**
 * Kml
 *
 * @author nhx
 * @date 2022-07-29
 */
@Data
@XStreamAlias("kml")
public class Kml {

    @XStreamAlias("xmlns")
    @XStreamAsAttribute
    private String xmlns;

    @XStreamAlias("xmlns:wpml")
    @XStreamAsAttribute
    private String wpml;

    @XStreamAlias("Document")
    private Document document;
}

Document对象:

package com.thcb.xml.bean.template;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;

/**
 * Document
 *
 * @author nhx
 * @date 2022-07-29
 */
@Data
@XStreamAlias("Document")
public class Document {

    /**
     * 文件创建作者
     */
    @XStreamAlias("wpml:author")
    private String author;

    /**
     * 文件创建时间(Unix Timestamp)
     */
    @XStreamAlias("wpml:createTime")
    private Long createTime;

    /**
     * 文件更新时间(Unix Timestamp)
     */
    @XStreamAlias("wpml:updateTime")
    private Long updateTime;

    /**
     * 任务信息
     */
    @XStreamAlias("wpml:missionConfig")
    private MissionConfig missionConfig;

    /**
     * 模板信息
     */
    @XStreamAlias("Folder")
    private Folder folder;
}

MissionConfig对象:

package com.thcb.xml.bean.template;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;

/**
 * MissionConfig
 *
 * @author nhx
 * @date 2022-07-29
 */
@Data
@XStreamAlias("wpml:missionConfig")
public class MissionConfig {

    /**
     * 飞向首航点模式
     */
    @XStreamAlias("wpml:flyToWaylineMode")
    private String flyToWaylineMode;

    /**
     * 航线结束动作
     */
    @XStreamAlias("wpml:finishAction")
    private String finishAction;

    /**
     * 失控是否继续执行航线
     */
    @XStreamAlias("wpml:exitOnRCLost")
    private String exitOnRCLost;

    /**
     * 失控动作类型
     */
    @XStreamAlias("wpml:executeRCLostAction")
    private String executeRCLostAction;

    /**
     * 安全起飞高度
     */
    @XStreamAlias("wpml:takeOffSecurityHeight")
    private String takeOffSecurityHeight;

    /**
     * 全局航线过渡速度
     */
    @XStreamAlias("wpml:globalTransitionalSpeed")
    private String globalTransitionalSpeed;

    /**
     * 参考起飞点
     */
    @XStreamAlias("wpml:takeOffRefPoint")
    private String takeOffRefPoint;

    /**
     * 参考起飞点海拔高度
     */
    @XStreamAlias("wpml:takeOffRefPointAGLHeight")
    private String takeOffRefPointAGLHeight;


    @XStreamAlias("wpml:globalRTHHeight")
    private String globalRTHHeight;

    /**
     * 飞行器机型信息
     */
    @XStreamAlias("wpml:droneInfo")
    private DroneInfo droneInfo;

    /**
     * 负载机型信息
     */
    @XStreamAlias("wpml:payloadInfo")
    private PayloadInfo payloadInfo;
}

Folder对象:

package com.thcb.xml.bean.template;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import lombok.Data;

import java.util.List;

/**
 * Folder
 *
 * @author nhx
 * @date 2022-07-29
 */
@Data
@XStreamAlias("Folder")
public class Folder {

    // 模板共用元素
    /**
     * 预定义模板类型
     */
    @XStreamAlias("wpml:templateType")
    private String templateType;


    @XStreamAlias("wpml:useGlobalTransitionalSpeed")
    private String useGlobalTransitionalSpeed;

    /**
     * 模板ID
     */
    @XStreamAlias("wpml:templateId")
    private String templateId;

    /**
     * 全局航线飞行速度
     */
    @XStreamAlias("wpml:autoFlightSpeed")
    private String autoFlightSpeed;

    @XStreamAlias("wpml:transitionalSpeed")
    private String transitionalSpeed;

    /**
     * 坐标系参数
     */
    @XStreamAlias("wpml:waylineCoordinateSysParam")
    private WaylineCoordinateSysParam waylineCoordinateSysParam;

    /**
     * 负载设置
     */
    @XStreamAlias("wpml:payloadParam")
    private PayloadParam payloadParam;


    // 航点飞行模板元素
    /**
     * 全局航点类型(全局航点转弯模式)
     */
    @XStreamAlias("wpml:globalWaypointTurnMode")
    private String globalWaypointTurnMode;

    /**
     * 全局航段轨迹是否尽量贴合直线
     */
    @XStreamAlias("wpml:globalUseStraightLine")
    private String globalUseStraightLine;

    /**
     * 云台俯仰角控制模式
     */
    @XStreamAlias("wpml:gimbalPitchMode")
    private String gimbalPitchMode;

    /**
     * 全局航线高度(椭球高)
     */
    @XStreamAlias("wpml:ellipsoidHeight")
    private String ellipsoidHeight;

    /**
     * 全局航线高度(EGM96海拔高/相对起飞点高度/AGL相对地面高度)
     */
    @XStreamAlias("wpml:height")
    private String height;

    /**
     * 全局偏航角模式参数
     */
    @XStreamAlias("wpml:globalWaypointHeadingParam")
    private GlobalWaypointHeadingParam globalWaypointHeadingParam;

    /**
     * 航点信息(包括航点经纬度和高度等)
     */
    @XStreamImplicit(itemFieldName = "Placemark")
    private List placemarkList;

    // 建图航拍模板元素
    /**
     * 是否开启标定飞行
     * 注:仅适用于M300RTK与L1机型
     */
    @XStreamAlias("wpml:caliFlightEnable")
    private String caliFlightEnable;

    /**
     * 是否开启高程优化
     */
    @XStreamAlias("wpml:elevationOpimizeEnable")
    private String elevationOpimizeEnable;

    /**
     * 是否开启智能摆拍
     * 注:仅适用于M300RTK与P1机型
     */
    @XStreamAlias("wpml:elevationOpimizeEnable")
    private String smartObliqueEnable;

    /**
     * 智能摆拍拍摄俯仰角
     * 注:仅适用于M300RTK与P1机型。P1机型云台建议输入范围[-90, -45]
     */
    @XStreamAlias("wpml:smartObliqueGimbalPitch")
    private String smartObliqueGimbalPitch;

    /**
     * 拍照模式(定时或定距)
     */
    @XStreamAlias("wpml:shootType")
    private String shootType;

    /**
     * 航线方向
     */
    @XStreamAlias("wpml:direction")
    private String direction;

    /**
     * 测区外扩距离
     */
    @XStreamAlias("wpml:margin")
    private String margin;

    /**
     * 重叠率参数
     */
    @XStreamAlias("wpml:overlap")
    private String overlap;

    /**
     * 全局航线高度(椭球高):ellipsoidHeight
     * 全局航线高度(EGM96海拔高/相对起飞点高度/AGL相对地面高度):height
     */

    /**
     * 测区多边形
     */
    @XStreamAlias("Polygon")
    private Polygon polygon;

    // 倾斜摄影模板元素
    /**
     * 云台俯仰角度(倾斜)
     */
    @XStreamAlias("wpml:inclinedGimbalPitch")
    private String inclinedGimbalPitch;

    /**
     * 航线飞行速度(倾斜)
     */
    @XStreamAlias("wpml:inclinedFlightSpeed")
    private String inclinedFlightSpeed;

    // 航带飞行模板元素
    /**
     * 是否开启单航线飞行
     */
    @XStreamAlias("wpml:singleLineEnable")
    private String singleLineEnable;

    /**
     * 每个子航带航线长度
     */
    @XStreamAlias("wpml:cuttingDistance")
    private String cuttingDistance;

    /**
     * 是否开启边缘优化
     */
    @XStreamAlias("wpml:boundaryOptimEnable")
    private String boundaryOptimEnable;

    /**
     * 航带左侧外扩距离
     */
    @XStreamAlias("wpml:leftExtend")
    private String leftExtend;

    /**
     * 航带右侧外扩距离
     */
    @XStreamAlias("wpml:rightExtend")
    private String rightExtend;

    /**
     * 是否包含中心线
     */
    @XStreamAlias("wpml:includeCenterEnable")
    private String includeCenterEnable;

    /**
     * 航点信息
     */
    @XStreamAlias("LineString")
    private LineString lineString;


    /**
     * 其他,参数无具体说明
     */
    @XStreamAlias("wpml:globalHeight")
    private String globalHeight;

}

这里就不把所有对象的代码都贴出来了,以上几个已经足够了,剩下的可以举一反三,自己创建出来。注意:如果想要解析xml,必须要把xml中的所有结构和标签都创建出来才可以,否则会报错。

4. 创建xml工具类

创建xml工具类,主要就是将xstream进行一个简单的封装

package com.thcb.xml.util;

import com.thcb.xml.bean.template.Kml;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * FileUtils
 *
 * @author nhx
 * @date 2022-08-01
 */
public class XmlUtils {

    /**
     * xstream初始化
     */
    private static final XStream XSTREAM = new XStream(new DomDriver());
    /**
     * 添加合法的包名,否则无法解析xml,使用时需要改成自己工程的包名
     */
    private static final String PACKET = "com.thcb.**";

    /**
     * 将xml字符串转为Kml对象
     *
     * @param xmlString xml字符串
     */
    public static Kml xmlToKml(String xmlString) {
        XSTREAM.allowTypesByWildcard(new String[]{PACKET});
        XSTREAM.processAnnotations(Kml.class);
        return (Kml) XSTREAM.fromXML(xmlString);
    }

    /**
     * 将Kml对象转为xml字符串
     *
     * @param kml Kml对象
     */
    public static String kmlToXml(Kml kml) {
        // 设置包名
        XSTREAM.allowTypesByWildcard(new String[]{PACKET});
        // 设置kml中的xmlns标签
        kml.setXmlns("http://www.opengis.net/kml/2.2");
        // 设置kml中的wpml标签
        kml.setWpml("http://www.dji.com/wpmz/1.0.0");
        // 转换的字符串前面加上xml说明
        return "\n" + XSTREAM.toXML(kml);
    }
}

5. 创建读取/写入文件工具类

由于需要读取和写入文件,这里就创建一个读写文件的工具类,便于操作。

package com.thcb.xml.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;

/**
 * FileUtils
 *
 * @author nhx
 * @date 2022-08-01
 */
public class FileUtils {

    /**
     * 将字符串写入指定路径的文件中
     *
     * @param encryptText 写入字符串
     * @param fileNameDec 写入文件路径
     * @param append      是否追加写入,true表示不覆盖原来的内容,而是加到文件的后面
     */
    public static void writerFile(String encryptText, String fileNameDec, boolean append) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(fileNameDec, append);
            writer.write(encryptText);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            System.out.println("写入文件发生了异常");
            e.printStackTrace();
        }
    }

    /**
     * 从指定路径的文件中读取字符串
     *
     * @param fileNameDec 读取文件路径
     */
    public static String readFile(String fileNameDec) {
        File file = new File(fileNameDec);
        long fileLengthLong = file.length();
        byte[] fileContent = new byte[(int) fileLengthLong];
        try {
            FileInputStream inputStream = new FileInputStream(file);
            inputStream.read(fileContent);
            inputStream.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
        return new String(fileContent);
    }
}

5. xml和对象的转换

好了,上面把需要的都创建完了,这里就可以进行转换了,xstream使用起来非常方便,转换过程只需一步:

package com.thcb.test;

import com.thcb.xml.util.FileUtils;
import com.thcb.xml.util.XmlUtils;
import com.thcb.xml.util.ZipUtils;
import com.thcb.xml.bean.template.Kml;

/**
 * XmlTest
 *
 * @author nhx
 * @date 2022-07-28
 */
public class XmlTest {

    public static void main(String[] args) {
        // 读取文件流
        String string = FileUtils.readFile("文件路径");

        try {
            // xml字符串转换成对象
            Kml kml = XmlUtils.xmlToKml(string);
            // log其中的一个属性值
            String coordinates = kml.getDocument().getFolder().getPlacemarkList().get(0).getPoint().getCoordinates().trim();
            System.out.println("coordinates:" + coordinates);

            // 修改其中几个属性值
            kml.getDocument().setUpdateTime(System.currentTimeMillis());
            kml.getDocument().setAuthor("nhx");
            // 对象转换成xml字符串
            String xml = XmlUtils.kmlToXml(kml);
            // log转换完的xml
            System.out.println("xml:\n" + xml);

            // 写入文件
            FileUtils.writerFile(xml, "文件路径", false);

        } catch (Exception e) {
            System.out.println(e.toString());
        }
        System.out.println("over");
    }
}

结语

至此,xml和对象的互相转换工作就完成了,还是比较简单的,有兴趣的可以看一下xstream的官网,在本文开头就贴出来官网地址了,上面有一些其他用法的介绍。
注:旧版本的xstream有安全漏洞,建议使用最新版本。

你可能感兴趣的:(java,后端,java,xml,开发语言)