文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java中操作Xml使用备忘[ Hutool工具类XmlUtil、XStream ]

2023-09-01 18:01

关注

文章目录

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯