近期因为结束无人机航线规划, 大量结束kml文件(近似xml的文件), 需要解析复杂xml, 了解到一些xml的解析工具,
DOM4J需要单独引入依赖, 其他三种, 作者目前使用jdk8完全可以使用(根据不同版本会有不同)
目前遇到的都是复杂xml, 主要使用JAXB解析文件, 其他几种都需要写代码, 匹配标签进行实体类的封装
元素
。注: 如果类型中使用多个命名空间, 建议所有@XmlRootElement、@Xmllement注解表明命名空间
作用和用法:
字段,方法,参数级别的注解。该注解可以将被注解的字段
(非静态),或者被注解的get/set方法对应的字段映射为本地元素,也就是子元素。
默认使用字段名或get/set方法去掉前缀剩下部分小写作为元素名(在字段名和get/set方法符合命名规范的情况下)。
属性:
该注解的属性常用的属性有有:name、nillable、required、namespace、defaultValue
元素的属性
,属性名默认使用字段名或get/set方法去掉前缀剩下部分首字母小写(在字段名和get/set方法符合命名规范的情况下)。忽略
被注解的类,字段,get/set对应字段。需要注意的是该注解与所有其他JAXB注释相互排斥,也就是说与其他注释连用就会报错。修改上面例子:注: 主要与@XmlElement位置有关
关键属性:
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TemplateType", propOrder = {
"document"
})
@XmlRootElement(name = "template", namespace = "http://www.abc.cn")
public class Template implements Cloneable {
@XmlElementRef(name = "Document", namespace = "http://www.abc.cn")
protected BaseDocumentType document;
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BaseDocumentType", propOrder = {
"author",
"createTime",
"updateTime",
})
@XmlSeeAlso({
TemplateDocument.class,
WaylineDocument.class
})
@XmlRootElement(name = "Document", namespace = "http://www.abc.cn")
public abstract class BaseDocument {
@XmlElement(name = "author", namespace = "http://www.abc.cn")
protected String author;
@XmlElement(name = "createTime", namespace = "http://www.abc.cn")
protected Long createTime;
@XmlElement(name = "updateTime", namespace = "http://www.abc.cn")
protected Long updateTime;
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TemplateDocumentType", propOrder = {
"folder"
})
@XmlRootElement(name = "Document", namespace = "http://www.abc.cn")
public abstract class TemplateDocument extends BaseDocument {
@XmlElement(name = "Folder", namespace = "http://www.def.cn")
protected String folder;
}
@Data
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TemplateDocumentType", propOrder = {
"folder"
})
@XmlRootElement(name = "Document", namespace = "http://www.abc.cn")
public abstract class WaylineDocument extends BaseDocument {
@XmlElement(name = "Wayline", namespace = "http://www.def.cn")
protected String Wayline;
}
@XmlElementRef(name = “Document”, namespace = “http://www.abc.cn”)
protected BaseDocumentType document;
这段代码, 会根据@XmlSeeAlso标识的类, 根据标签不同自动匹配
@Slf4j
public class KMLUtil {
/** xml 转 对象 */
public static Template parse(Class<?> clazz, InputStream inputStream) throws JAXBException {
log.debug("[param:parse]==>clazz:{}, inputStream:{}", clazz, inputStream);
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
return (WayLine)unmarshaller.unmarshal(inputStream);
}
/** 对象 转 xml */
public static void format(Template template, String path) throws JAXBException, IOException {
log.debug("[param:parse]==>wayline:{}, path:{}", template, path);
JAXBContext jaxbContext = JAXBContext.newInstance(template.getClass());
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// 禁用默认的XML声明
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
File file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
file.createNewFile();
} else {
file.delete();
file.createNewFile();
}
StringWriter sw = new StringWriter();
sw.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
marshaller.marshal(wayline, sw);
FileWriter fw = new FileWriter(path);
fw.write(sw.toString());
fw.flush();
fw.close();
}
}