- List item
文章目录
- Java中操作Xml使用备忘[ Hutool工具类XmlUtil、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. 写XMLXmlUtil.toStr 将XML文档转换为StringXmlUtil.toFile 将XML文档写入到文件3. 创建XMLXmlUtil.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 创建XPathgetByXPath 通过XPath方式读取XML节点等信息
2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用]
2-1 Hutool工具包Maven依赖和测试Xml字符串如下
<dependency> <groupId>cn.hutoolgroupId> <artifactId>hutool-allartifactId> <version>5.8.16version>dependency>
<returnsms> <returnstatus>Success(成功)returnstatus> <message>okmessage> <remainpoint>1490remainpoint> <taskID>885taskID> <successCounts>1successCounts> returnsms>
2-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示例字符串如下
<forms version="2.1"> <formExport> <summary id="1132755668421070367" name="formmain_0031"/> <definitions> <column id="field0001" type="0" name="field1" length="255"/> <column id="field0002" type="0" name="field2" length="256"/> definitions> <values> <column name="field1"> <value> 建行一世 value> column> <column name="field2"> <value> 中国人民 value> column> values> <subForms/> formExport>forms>
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());//读取属性lengthSystem.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 <nodeList.getLength() ; i++) { //打印标签的文本 System.out.println(nodeList.item(i).getTextContent());}
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 <nodeList.getLength() ; i++) { //打印标签的文本 System.out.println(nodeList.item(i).getTextContent());}System.out.println(XmlUtil.toStr(document));// 打印的结果: 在建行一世 后,新增了一个从零开始
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 <nodeList.getLength() ; i++) { //打印标签的文本 System.out.println(nodeList.item(i).getTextContent());}//修改for (int i = 0; i <nodeList.getLength() ; i++) { // ******************* 这里进行修改 ******************** nodeList.item(i).setTextContent("张三丰");}//第二次打印for (int i = 0; i <nodeList.getLength() ; i++) { //打印标签的文本 System.out.println(nodeList.item(i).getTextContent());}// 打印输出结果: //第一次打印输出为: 建行一世//第二次打印输出为: 张三丰
4 依赖Hutool再次封装的工具类XmlUtil,实现xml-map、map-xml、xml-json功能
// 作用:// 1.xml转map// 2.xml转json// 3.map转xml
4-1 需要添加的依赖
<dependency> <groupId>cn.hutoolgroupId> <artifactId>hutool-allartifactId> <version>5.7.15version>dependency> <dependency> <groupId>org.dom4jgroupId> <artifactId>dom4jartifactId> <version>2.1.3version>dependency>
4-2 工具类XmlUtil代码
4-2-1 用到的一个枚举XmlSort如下:
import java.util.HashMap;import java.util.LinkedHashMap; public enum XmlSort{ SORT(LinkedHashMap.class,"有序"), NO_SORT(HashMap.class,"无序"); 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; public class XmlUtil { private final static String TAG_ATTR = "attr"; private XmlSort xmlSort = XmlSort.NO_SORT; public String mapToXml(Map<String,Object> 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<String, Object>)obj); return document.asXML(); } public void mapNodes(Element node, Map<String, Object> map) { map.forEach((k,v)->{ Object obj = map.get(k); // 给当前父类添加属性 if(TAG_ATTR.equals(k)){ Assert.isAssignable(Map.class,obj.getClass()); Map<String,Object> tagMap = (Map<String,Object>) obj; tagMap.forEach((tagKey,tagValue)->{ node.addAttribute(tagKey, (String) tagValue); }); return ; } if(obj instanceof Map){ Element newElement = node.addElement(k); // map 处理 Map<String,Object> childMap = (Map<String,Object>) obj; mapNodes(newElement,childMap); }else if (obj instanceof String){ Element newElement = node.addElement(k); newElement.setText((String) v); } else if (obj instanceof List) { List<Map<String, Object>> list = (List<Map<String, Object>>) obj; list.forEach(itemMap->{ Element newElement = node.addElement(k); mapNodes(newElement,itemMap); }); } }); } public String xmlToJson(String fileName) throws DocumentException { Map<String, Object> xmlMap = xmlToMap(fileName); return JSONUtil.toJsonStr(xmlMap); } public Map<String, Object> xmlToMap(String fileName) throws DocumentException { // 创建saxReader对象 SAXReader reader = new SAXReader(); // 通过read方法读取一个文件 转换成Document对象 Document document = reader.read(new File(fileName)); //获取根节点元素对象 Element node = document.getRootElement(); //遍历所有的元素节点 Map<String, Object> map = getNewMap(); // 处理节点 listNodes(node, map); return map; } public void listNodes(Element node, Map<String, Object> map) { Map<String, Object> xiaoMap = getNewMap(); String nodeKey = node.getName(); // 获取当前节点的所有属性节点 List<Attribute> list = node.attributes(); // 遍历属性节点 Map<String, Object> attrMap = getNewMap(); for (Attribute attr : list) { attrMap.put(attr.getName(), attr.getValue()); } if (ObjectUtil.isNotEmpty(attrMap)) { xiaoMap.put(TAG_ATTR, attrMap); } // 当前节点下面子节点迭代器 Iterator<Element> 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<Map<String, Object>> childList = null; // 获取原来的 Object obj = map.get(nodeKey); if (obj instanceof Iterable) { // 非第一个 childList = (List<Map<String, Object>>) obj; childList.add(xiaoMap); } else if (obj instanceof Map) { // 第一个 Map<String, Object> childMap = (Map<String, Object>) obj; childList = new ArrayList<>(); childList.add(childMap); childList.add(xiaoMap); } // 添加新的 map.put(nodeKey, childList); } } // 遍历 while (it.hasNext()) { // 获取某个子节点对象 Element e = it.next(); // 对子节点进行遍历 listNodes(e, xiaoMap); } } private Map<String, Object> getNewMap() { Object obj = null; try { obj = xmlSort.getMapClass().newInstance(); if (obj instanceof Map) { return (Map<String, Object>) obj; } } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return null; } public void setXmlSort(XmlSort xmlSort) { this.xmlSort = xmlSort; }}
5 JavaBean与Xml互转_使用XStream实现,很实用 [强烈推荐使用]
说明:
相对于JAXB,XStream更简洁一些。
常用注解:
@XStreamAlias:定义xml节点名
5-1 引入XStream依赖
<dependency><groupId>com.thoughtworks.xstreamgroupId><artifactId>xstreamartifactId><version>1.4.19version>dependency>
5-2 工具类XStreamXmlBeanUtil
import com.thoughtworks.xstream.XStream; public class XStreamXmlBeanUtil { public static String toXml(Object bean) { return initXStream(bean.getClass()).toXML(bean); } @SuppressWarnings("unchecked") public static <T> T fromXml(String xml, Class<T> 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;}
来源地址:https://blog.csdn.net/qq_17847881/article/details/130855130