跳转到主内容
极星编程网:以代码为星,赴技术山海!

Java中操作Xml使用方法备忘录(Hutool工具类XmlUtil、XStream)

目录

1. Hutool中XmlUtil的使用简介

2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用]2-1 Hutool工具包Maven依赖和测试Xml字符串如下2-2 读取Xml中的节点的值

3. Hutool中XmlUtil详细操作示例

3-1 Xml示例字符串如下3-2 查询标签内的属性3-3 查询一对标签中的文本3-4 查询Xml后,再新增一个标签并赋值3-5 修改一个标签数据4 依赖Hutool再次封装的工具类XmlUtil,实现xml-map、map-xml、xml-json功能4-1 需要添加的依赖4-2 工具类XmlUtil代码4-2-1 用到的一个枚举XmlSort如下:4-2-2 XmlUtil.java如下5 JavaBean与Xml互转_使用XStream实现,很实用 [强烈推荐使用]5-1 引入XStream依赖5-2 工具类XStreamXmlBeanUtil 5-3 使用实例5-4 关于XStream更详细的使用,如设置别名、设置属性、隐藏集合根节点等,请参考如下博文总结

1. Hutool中XmlUtil的使用简介

# 说明1: XmlUtil只是w3c dom的简单工具化封装,减少操作dom的难度,

#         如果项目对XML依赖较大,依旧推荐Dom4j框架

# 说明2:JDK已经封装有XML解析和构建工具:w3c dom

#         Hutool中XmlUtil简化XML的创建、读、写

1. 读取XML

读取XML分为两个方法:

XmlUtil.readXML 读取XML文件

XmlUtil.parseXml 解析XML字符串为Document对象

2. 写XML

XmlUtil.toStr     将XML文档转换为String

XmlUtil.toFile     将XML文档写入到文件

3. 创建XML

XmlUtil.createXml 创建XML文档, 创建的XML默认是utf8编码,

修改编码的过程是在toStr和toFile方法里,既XML在转为文本的时候才定义编码。

4. XML读取操作

通过以下工具方法,可以完成基本的节点读取操作。

XmlUtil.cleanInvalid 除XML文本中的无效字符

XmlUtil.getElements 根据节点名获得子节点列表

XmlUtil.getElement 根据节点名获得第一个子节点

XmlUtil.elementText 根据节点名获得第一个子节点

XmlUtil.transElements 将NodeList转换为Element列表

5. XML与对象转换

writeObjectAsXml 将可序列化的对象转换为XML写入文件,已经存在的文件将被覆盖。

readObjectFromXml 从XML中读取对象。

注意 这两个方法严重依赖JDK的XMLEncoder和XMLDecoder,

生成和解析必须成对存在(遵循固定格式),普通的XML转Bean会报错。

6. Xpath操作

createXPath 创建XPath

getByXPath     通过XPath方式读取XML节点等信息2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用]2-1 Hutool工具包Maven依赖和测试Xml字符串如下cn.hutoolhutool-all5.8.16Success(成功)ok149088512-2 读取Xml中的节点的值Document docResult=XmlUtil.readXML(xmlFile);// 结果为“ok”

Object value = XmlUtil.getByXPath("//returnsms/message", docResult, XPathConstants.STRING);

// 说明:Element对象目前仅能支持一层一层的向下解析,所以请不要跳级去做查询,// 否则会报null。如果想直接获取到某个标签的文本,在有准确定位的情况下// 可以直接写出路径获取,// 但是如果该层级存在相同的标签则只获取第一个标签的数据。

String xmlData="xml字符串";Document document= XmlUtil.parseXml(xmlData);//获得XML文档根节点Element elementG=XmlUtil.getRootElement(document);//通过固定路径获取到数据Object bString = XmlUtil.getByXPath("//root/base/message/event_no", document, XPathConstants.STRING);System.out.println("event_no元素节点值:"+bString);

3. Hutool中XmlUtil详细操作示例

3-1 Xml示例字符串如下

建行一世中国人民

3-2 查询标签内的属性// 例: 获取标签中第一个标签属性length的值

String xmlData="上面规定的xml字符串"; // 测试时自己替换下Document document= XmlUtil.parseXml(xmlData);//获得XML文档根节点Element elementG=XmlUtil.getRootElement(document);//打印节点名称System.out.println(elementG.getTagName());//获取下层节点(该方法默认取第一个)

Element elementZ=XmlUtil.getElement(elementG,"formExport");System.out.println(elementZ.getTagName());//获取下层节点(该方法默认取第一个)

Element elementZ1=XmlUtil.getElement(elementZ,"definitions");System.out.println(elementZ1.getTagName());//获取下层节点(该方法默认取第一个)

Element elementZ2=XmlUtil.getElement(elementZ1,"column");System.out.println(elementZ2.getTagName());

//读取属性length System.out.println(elementZ2.getAttribute("length"));3-3 查询一对标签中的文本// 例:获取标签中第一个标签下的所包含的文本,可直接看最后一行

// =======以下内容同3-2,内容开始========================================String xmlData="上面规定的xml字符串";Document document= XmlUtil.parseXml(xmlData);//获得XML文档根节点Element elementG=XmlUtil.getRootElement(document);//获取下层节点(该方法默认取第一个)

Element elementZ=XmlUtil.getElement(elementG,"formExport");//获取下层节点(该方法默认取第一个)

Element elementZ_1=XmlUtil.getElement(elementZ,"values");//获取下层节点(该方法默认取第一个)

Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");// =======以上内容同3-2,内容结束========================================

//获取到所有子标签 // Value返回的时NodeList,遍历获取即可NodeList nodeList=elementZ_2.getElementsByTagName("value");for (int i = 0; i 3-4 查询Xml后,再新增一个标签并赋值// 例:给标签中第一个标签下再度添加一个标签,所包含的文本为:从零开始

// =======以下内容同3-2,内容开始========================================String xmlData="上面规定的xml字符串";Document document= XmlUtil.parseXml(xmlData);//获得XML文档根节点Element elementG=XmlUtil.getRootElement(document);//获取下层节点(该方法默认取第一个)

Element elementZ=XmlUtil.getElement(elementG,"formExport");//获取下层节点(该方法默认取第一个)

Element elementZ_1=XmlUtil.getElement(elementZ,"values");//获取下层节点(该方法默认取第一个)

Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");// =======以上内容同3-2,内容结束========================================

//创建一个标签Element elementItem = document.createElement("value");//赋值elementItem.setTextContent("从零开始");//放到某个标签下面elementZ_2.appendChild(elementItem);//获取到所有子标签NodeList nodeList=elementZ_2.getElementsByTagName("value");for (int i = 0; i

// 打印的结果: 在建行一世后,新增了一个从零开始3-5 修改一个标签数据// 例:给标签中第一个标签下的第一个标签修改成:张三丰

// =======以下内容同3-2,内容开始========================================String xmlData="上面规定的xml字符串";Document document= XmlUtil.parseXml(xmlData);//获得XML文档根节点Element elementG=XmlUtil.getRootElement(document);//获取下层节点(该方法默认取第一个)

Element elementZ=XmlUtil.getElement(elementG,"formExport");//获取下层节点(该方法默认取第一个)

Element elementZ_1=XmlUtil.getElement(elementZ,"values");//获取下层节点(该方法默认取第一个)

Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");// =======以上内容同3-2,内容结束========================================

//获取到所有子标签NodeList nodeList=elementZ_2.getElementsByTagName("value");//第一次打印for (int i = 0; i 4 依赖Hutool再次封装的工具类XmlUtil,实现xml-map、map-xml、xml-json功能// 作用:

//     1.xml转map

//     2.xml转json

//     3.map转xml 4-1 需要添加的依赖cn.hutoolhutool-all5.7.15

org.dom4jdom4j2.1.34-2 工具类XmlUtil代码4-2-1 用到的一个枚举XmlSort如下:import java.util.HashMap;import java.util.LinkedHashMap;

/*** xml解析顺序是否有序* @author ASen*/

public enum XmlSort{/*** 有序*/ SORT(LinkedHashMap.class,"有序"),/*** 无序*/ NO_SORT(HashMap.class,"无序");

/*** 创建的map字节码对象*/ private final Class mapClass;

/*** 顺序名称*/ private final String message ;

XmlSort(Class mapClass, String message) {this.mapClass = mapClass;this.message = message;}

public Class getMapClass() {return mapClass;}

public String getMessage() {return message;}}4-2-2 XmlUtil.java如下package com.asen.demo.util;

import cn.hutool.core.lang.Assert;import cn.hutool.core.util.ObjectUtil;import cn.hutool.json.JSONUtil;import com.asen.demo.constant.XmlSort;import org.dom4j.Attribute;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.dom4j.tree.DefaultDocument;import org.dom4j.tree.DefaultElement;

import java.io.File;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;

/*** xml解析帮组类* @author asen* @date 2022/1/10 15:17*/ public class XmlUtil {

/*** 标签属性*/ private final static String TAG_ATTR = "attr";

/*** 创建的map类型*/ private XmlSort xmlSort = XmlSort.NO_SORT;

/*** map to xml* @param map map对象* @return xml 字符串*/ public String mapToXml(Map map) {if(map.size() != 1){throw new RuntimeException("map根节点长度不为1");}String key = "";for (String str : map.keySet()) {key = str ;}// 创建根节点Element rootElement = new DefaultElement(key);Document document = new DefaultDocument(rootElement);Element node = document.getRootElement();Object obj = map.get(key);// 断言Assert.isAssignable(Map.class,obj.getClass());mapNodes(node,(Map)obj);return document.asXML();}

/*** 父类节点已经创建, map 包含父类* @param node node* @param map map*/ public void mapNodes(Element node, Map map) {map.forEach((k,v)->{Object obj = map.get(k);// 给当前父类添加属性if(TAG_ATTR.equals(k)){Assert.isAssignable(Map.class,obj.getClass());Map tagMap = (Map) obj;tagMap.forEach((tagKey,tagValue)->{node.addAttribute(tagKey, (String) tagValue);});return ;}if(obj instanceof Map){Element newElement = node.addElement(k);// map 处理Map childMap = (Map) obj;mapNodes(newElement,childMap);}else if (obj instanceof String){Element newElement = node.addElement(k);newElement.setText((String) v);} else if (obj instanceof List) {List> list = (List>) obj;list.forEach(itemMap->{Element newElement = node.addElement(k);mapNodes(newElement,itemMap);});}});}

/*** 读取xml文件,返回json字符串** @param fileName 文件路径* @return json字符串* @throws DocumentException 异常*/ public String xmlToJson(String fileName) throws DocumentException {Map xmlMap = xmlToMap(fileName);return JSONUtil.toJsonStr(xmlMap);}

/*** 读取xml文件,返回map对象** @param fileName 文件路径* @return map对象* @throws DocumentException 异常*/ public Map xmlToMap(String fileName) throws DocumentException {// 创建saxReader对象SAXReader reader = new SAXReader();// 通过read方法读取一个文件 转换成Document对象Document document = reader.read(new File(fileName));//获取根节点元素对象Element node = document.getRootElement();//遍历所有的元素节点Map map = getNewMap();// 处理节点listNodes(node, map);return map;}

/*** 遍历当前节点元素下面的所有(元素的)子节点** @param node node*/ public void listNodes(Element node, Map map) {Map xiaoMap = getNewMap();String nodeKey = node.getName();// 获取当前节点的所有属性节点List list = node.attributes();// 遍历属性节点Map attrMap = getNewMap();for (Attribute attr : list) {attrMap.put(attr.getName(), attr.getValue());}if (ObjectUtil.isNotEmpty(attrMap)) {xiaoMap.put(TAG_ATTR, attrMap);}

// 当前节点下面子节点迭代器Iterator it = node.elementIterator();

if (!("".equals(node.getTextTrim())) || !it.hasNext()) {map.put(nodeKey, node.getTextTrim());}else{// 不为空if (ObjectUtil.isEmpty(map.get(nodeKey))) {map.put(nodeKey, xiaoMap);} else {List> childList = null;// 获取原来的Object obj = map.get(nodeKey);if (obj instanceof Iterable) {// 非第一个childList = (List>) obj;childList.add(xiaoMap);} else if (obj instanceof Map) {// 第一个Map childMap = (Map) obj;childList = new ArrayList<>();childList.add(childMap);childList.add(xiaoMap);}// 添加新的map.put(nodeKey, childList);}}

// 遍历while (it.hasNext()) {// 获取某个子节点对象Element e = it.next();// 对子节点进行遍历listNodes(e, xiaoMap);}}

/*** 获取一个新的map对象** @return map对象*/ private Map getNewMap() {Object obj = null;try {obj = xmlSort.getMapClass().newInstance();if (obj instanceof Map) {return (Map) obj;}} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();}return null;}

/*** 设置是否排序** @param xmlSort 是否排序对象*/ public void setXmlSort(XmlSort xmlSort) {this.xmlSort = xmlSort;}}5 JavaBean与Xml互转_使用XStream实现,很实用 [强烈推荐使用]

说明:

相对于JAXB,XStream更简洁一些。

常用注解:

@XStreamAlias:定义xml节点名@XStreamAsAttribute:把字段节点设置成属性5-1 引入XStream依赖com.thoughtworks.xstreamxstream1.4.195-2 工具类XStreamXmlBeanUtilimport com.thoughtworks.xstream.XStream;

/*** XStream 实现bean与xml之间相互转换*/ public class XStreamXmlBeanUtil {/*** JavaBean转XML* @param bean - JavaBean* @return - XML*/ public static String toXml(Object bean) {return initXStream(bean.getClass()).toXML(bean);}

/*** XML转JavaBean* @param xml - XML* @param beanClazz - JavaBean Class* @param * @return - JavaBean*/@SuppressWarnings("unchecked") public static T fromXml(String xml, Class beanClazz) {return (T) initXStream(beanClazz).fromXML(xml);}

private static XStream initXStream(Class beanClazz) {XStream x = new XStream();x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,TimeZone.getTimeZone("GMT+8")));

//不使用默认的类加载器,需要手动设置类加载器x.setClassLoader(beanClazz.getClassLoader());x.processAnnotations(beanClazz);x.allowTypesByRegExp(new String[]{".*"});// 开起注解功能x.autodetectAnnotations(true);// 忽律未知字段x.ignoreUnknownElements();return x;}}5-3 使用实例import com.thoughtworks.xstream.annotations.XStreamAlias;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;

public class Test {public static void main(String[] args) {// 1. 普通bean与Xml互转User user = new User("貂蝉", 18, "女");System.out.println("============普通bean转Xml===============");String xml = XStreamXmlBeanUtil.toXml(user);System.out.println(xml);System.out.println("============Xml转普通bean===============");System.out.println(XStreamXmlBeanUtil.fromXml(xml, User.class));

// 2. 继承bean与Xml互转Child child = new Child("吃糖葫芦");child.setName("葫芦娃");child.setAge(2);child.setGender("男");child.setHobby("打游戏");

System.out.println("============继承bean转Xml===============");xml = XStreamXmlBeanUtil.toXml(child);System.out.println(xml);System.out.println("============Xml转继承bean====");// 生成的Xml仅有Child的属性hobby,但转后后的Child对象,父属性都是有值的;

System.out.println(XStreamXmlBeanUtil.fromXml(xml, Child.class));System.out.println("============Xml转继承bean,测试转换后,父属性、自身属性是否有值====");Child c2 = XStreamXmlBeanUtil.fromXml(xml, Child.class);System.out.println( "11111==" + c2.getName() + c2.getGender() + c2.getHobby());

// 输出内容如下:// ============普通bean转Xml===============// // 貂蝉// 18// 女// // ============Xml转普通bean===============// XmlTest.User(name=貂蝉, age=18, gender=女)// ============继承bean转Xml===============// // 葫芦娃// 2// 男// 打游戏// // ============Xml转继承bean====// XmlTest.Child(hobby=打游戏)// 11111==葫芦娃男打游戏}}

@Data@NoArgsConstructor@AllArgsConstructor@XStreamAlias("Women") class User {private String name;private int age;private String gender;}

@NoArgsConstructor@AllArgsConstructor@Data@XStreamAlias("User") class Child extends User {private String hobby;}5-4 关于XStream更详细的使用,如设置别名、设置属性、隐藏集合根节点等,请参考如下博文XStream使用详解总结到此这篇关于Java中操作Xml使用方法备忘录的文章就介绍到这了,更多相关Java操作Xml使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:Java操作XML工具类XmlUtil详解XmlUtils JS操作XML工具类Android开发中解析xml文件XmlUtils工具类与用法示例

相关文章