java使用xstream实现xml文件和对象之间的相互转换
作者:天河归来
java使用xstream实现xml文件和对象之间的相互转换
整体描述
xml是一个用途比较广泛的文件类型,在java里也自带解析xml的包,但是本文使用的是xstream来实现xml和对象之间的相互转换,xstream是一个第三方开源框架,使用起来比较方便,xstream官网地址: xstream官网,目前最新版本是1.4.19。
具体实现
1. 引入xstream的maven
添加xstream的依赖,这里使用最新的1.4.19版本
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.19</version> </dependency>
2.xml文件
这里使用的是大疆无人机的地图文件template.kml :
xml文件参考文档:大疆云上API地址: 大疆云上API。
文件具体格式如下,基本包含了xml所有需要使用的示例。
注:文件虽然是.kml格式,但其实就是xml的格式。
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.0"> <Document> <!-- Step 1: Implement File Creation Information --> <wpml:author>Name</wpml:author> <wpml:createTime>1637600807044</wpml:createTime> <wpml:updateTime>1637600875837</wpml:updateTime> <!-- Step 2: Setup Mission Configuration --> <wpml:missionConfig> <wpml:flyToWaylineMode>safely</wpml:flyToWaylineMode> <wpml:finishAction>goHome</wpml:finishAction> <wpml:exitOnRCLost>goContinue</wpml:exitOnRCLost> <wpml:takeOffSecurityHeight>20</wpml:takeOffSecurityHeight> <wpml:globalTransitionalSpeed>10</wpml:globalTransitionalSpeed> <wpml:droneInfo> <!-- Declare drone model with M30 --> <wpml:droneEnumValue>67</wpml:droneEnumValue> <wpml:droneSubEnumValue>0</wpml:droneSubEnumValue> </wpml:droneInfo> <wpml:payloadInfo> <!-- Declare payload model with M30 --> <wpml:payloadEnumValue>52</wpml:payloadEnumValue> <wpml:payloadSubEnumValue>0</wpml:payloadSubEnumValue> <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex> </wpml:payloadInfo> </wpml:missionConfig> <!-- Step 3: Setup A Folder for Waypoint Template --> <Folder> <wpml:templateType>waypoint</wpml:templateType> <wpml:useGlobalTransitionalSpeed>0</wpml:useGlobalTransitionalSpeed> <wpml:templateId>0</wpml:templateId> <wpml:waylineCoordinateSysParam> <wpml:coordinateMode>WGS84</wpml:coordinateMode> <wpml:heightMode>EGM96</wpml:heightMode> <wpml:ellipsoidHeight>100</wpml:ellipsoidHeight> <wpml:height>100</wpml:height> <wpml:positioningType>GPS</wpml:positioningType> </wpml:waylineCoordinateSysParam> <wpml:autoFlightSpeed>7</wpml:autoFlightSpeed> <wpml:transitionalSpeed>7</wpml:transitionalSpeed> <wpml:gimbalPitchMode>usePointSetting</wpml:gimbalPitchMode> <wpml:globalWaypointHeadingParam> <wpml:waypointHeadingMode>followWayline</wpml:waypointHeadingMode> </wpml:globalWaypointHeadingParam> <wpml:globalWaypointTurnMode>toPointAndStopWithDiscontinuityCurvature</wpml:globalWaypointTurnMode> <Placemark> <Point> <!-- Fill longitude and latitude here --> <coordinates> longitude,latitude </coordinates> </Point> <wpml:index>0</wpml:index> <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight> <wpml:height>100</wpml:height> <wpml:useGlobalHeight>1</wpml:useGlobalHeight> <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed> <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam> <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam> <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle> </Placemark> <Placemark> <Point> <!-- Fill longitude and latitude here --> <coordinates> longitude,latitude </coordinates> </Point> <wpml:index>1</wpml:index> <wpml:ellipsoidHeight>90.2</wpml:ellipsoidHeight> <wpml:height>100</wpml:height> <wpml:useGlobalHeight>1</wpml:useGlobalHeight> <wpml:useGlobalSpeed>1</wpml:useGlobalSpeed> <wpml:useGlobalHeadingParam>1</wpml:useGlobalHeadingParam> <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam> <wpml:gimbalPitchAngle>0</wpml:gimbalPitchAngle> <!-- Declare action group for waypoint 1# --> <wpml:actionGroup> <wpml:actionGroupId>0</wpml:actionGroupId> <wpml:actionGroupStartIndex>1</wpml:actionGroupStartIndex> <wpml:actionGroupEndIndex>1</wpml:actionGroupEndIndex> <wpml:actionGroupMode>sequence</wpml:actionGroupMode> <wpml:actionTrigger> <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType> </wpml:actionTrigger> <!-- Declare the 1st action: rotate gimbal --> <wpml:action> <wpml:actionId>0</wpml:actionId> <wpml:actionActuatorFunc>gimbalRotate</wpml:actionActuatorFunc> <wpml:actionActuatorFuncParam> <wpml:gimbalRotateMode>absoluteAngle</wpml:gimbalRotateMode> <wpml:gimbalPitchRotateEnable>0</wpml:gimbalPitchRotateEnable> <wpml:gimbalPitchRotateAngle>0</wpml:gimbalPitchRotateAngle> <wpml:gimbalRollRotateEnable>0</wpml:gimbalRollRotateEnable> <wpml:gimbalRollRotateAngle>0</wpml:gimbalRollRotateAngle> <wpml:gimbalYawRotateEnable>1</wpml:gimbalYawRotateEnable> <wpml:gimbalYawRotateAngle>30</wpml:gimbalYawRotateAngle> <wpml:gimbalRotateTimeEnable>0</wpml:gimbalRotateTimeEnable> <wpml:gimbalRotateTime>0</wpml:gimbalRotateTime> <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex> </wpml:actionActuatorFuncParam> </wpml:action> <!-- Declare the 2nd action: take photo --> <wpml:action> <wpml:actionId>1</wpml:actionId> <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc> <wpml:actionActuatorFuncParam> <wpml:fileSuffix>point1</wpml:fileSuffix> <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex> </wpml:actionActuatorFuncParam> </wpml:action> </wpml:actionGroup> </Placemark> </Folder> </Document> </kml>
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<Placemark> 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 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + XSTREAM.toXML(kml); } }
5. 创建读取/写入文件工具类
由于需要读取和写入文件,这里就创建一个读写文件的工具类,便于操作。
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 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + XSTREAM.toXML(kml); } }
6. 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使用xstream实现xml文件和对象之间的相互转换的文章就介绍到这了,更多相关java xml文件和对象转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!