• List item

文章目录

  • Java中操作Xml使用备忘
    • 1. Hutool中XmlUtil的使用简介
    • 2. Hutool中XmlUtil快速读取Xml字符串某个节点值 [简单取值时,推荐使用]
      • 2-1 Hutool工具包Maven依赖和测试Xml字符串如下
      • 2-2 读取Xml中的节点<message>的值
    • 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 使用实例

Java中操作Xml使用备忘

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字符串如下

<!-- 引入Hutool的Maven依赖 -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version>
</dependency>
<!-- 下方测试用的Xml字符串 -->
<?xml version="1.0" encoding="utf-8"?>
<returnsms> <returnstatus>Success(成功)</returnstatus>  <message>ok</message>  <remainpoint>1490</remainpoint>  <taskID>885</taskID>  <successCounts>1</successCounts>
</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 查询标签内的属性

// 例: 获取<definitions>标签中第一个标签<column >属性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 查询一对标签中的文本

// 例:获取<values>标签中第一个标签<column>下的<value>所包含的文本,可直接看最后一行// =======以下内容同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后,再新增一个标签并赋值

// 例:给<values>标签中第一个标签<column>下再度添加一个<value>标签,所包含的文本为:从零开始// =======以下内容同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));// 打印的结果: 在<value>建行一世</value>后,新增了一个<value>从零开始</value>

3-5 修改一个标签数据

// 例:给<values>标签中第一个标签<column>下的第一个<value>标签修改成:张三丰// =======以下内容同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.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.15</version>
</dependency><dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version>
</dependency>

4-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<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();}/*** 父类节点已经创建, map 包含父类* @param node node* @param map map*/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);});}});}/*** 读取xml文件,返回json字符串** @param fileName 文件路径* @return json字符串* @throws DocumentException 异常*/public String xmlToJson(String fileName) throws DocumentException {Map<String, Object> xmlMap = xmlToMap(fileName);return JSONUtil.toJsonStr(xmlMap);}/*** 读取xml文件,返回map对象** @param fileName 文件路径* @return map对象* @throws DocumentException 异常*/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;}/*** 遍历当前节点元素下面的所有(元素的)子节点** @param node node*/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);}}/*** 获取一个新的map对象** @return map对象*/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;}/*** 设置是否排序** @param xmlSort 是否排序对象*/public void setXmlSort(XmlSort xmlSort) {this.xmlSort = xmlSort;}
}

5 JavaBean与Xml互转_使用XStream实现,很实用 [强烈推荐使用]

说明:
相对于JAXB,XStream更简洁一些。
常用注解:
@XStreamAlias:定义xml节点名

5-1 引入XStream依赖

<dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.19</version>
</dependency>

5-2 工具类XStreamXmlBeanUtil

import 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 <T>* @return - JavaBean*/@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===============//        <Women>//          <name>貂蝉</name>//          <age>18</age>//          <gender>女</gender>//        </Women>//        ============Xml转普通bean===============//        XmlTest.User(name=貂蝉, age=18, gender=女)//        ============继承bean转Xml===============//        <User>//          <name>葫芦娃</name>//          <age>2</age>//          <gender>男</gender>//          <hobby>打游戏</hobby>//        </User>//        ============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;
}

Java中操作Xml使用备忘相关推荐

  1. Java 中的 XML:Java 文档模型的用法

    Java 中的 XML:Java 文档模型的用法 英文原文 内容: 代码对比 DOM JDOM dom4j Electric XML XPP 结束语 下一次... 参考资料 关于作者 对本文的评价 相 ...

  2. 【转载】 详细介绍Flex中操作XML

    一  在介绍Flex中操作XML之前,首先简单介绍下XML中的基本术语. 元素:XML中拥有开始标签和结束标签的这一块称为"元素"     节点:把XML元素与文本结合起来统称为节 ...

  3. 宣布EAXY:使Java中的XML更容易

    Java中的XML库是一个雷区. 操作和读取XML所需的代码量令人震惊,使用不同的库遇到类路径问题的风险很大,并且对名称空间的处理带来许多混乱和错误. 最糟糕的是,情况似乎并没有改善. 一位同事让我意 ...

  4. 宣布EAXY:在Java中简化XML

    Java中的XML库是一个雷区. 操作和读取XML所需的代码量令人震惊,使用不同的库遇到类路径问题的风险很大,并且命名空间的处理带来了很多混乱和错误. 最糟糕的是,情况似乎并没有改善. 一位同事让我意 ...

  5. java 解析/操作 xml 几种常用方式 xml的增加/删除/修改

    java 解析/操作 xml 几种常用方式 xml的增加/删除/修改 首先,我们先介绍几种常用的xml解析器. 1. 介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方 ...

  6. 如何从Java中打印XML?

    本文翻译自:How to pretty print XML from Java? I have a Java String that contains XML, with no line feeds ...

  7. VC++中操作XML(MFC、SDK)

    VC++中操作XML(MFC.SDK) XML在Win32程序方面应该没有在Web方面应用得多,很多Win32程序也只是用XML来存存配置信息而已,而且没有足够的好处的话还不如用ini.VC++里操作 ...

  8. java中拼写xml

    本文为博主原创,未经博主允许,不得转载: xml具有强大的功能,在很多地方都会用的到.比如在通信的时候,通过xml进行消息的发送和交互. 在项目中有很多拼写xml的地方,进行一个简单的总结. 先举例如 ...

  9. matlab分析xml文件_如何在Java中读取XML文件(DOM分析器)

    matlab分析xml文件 Today we will learn how to read the XML file in Java. We will also learn how to parse ...

最新文章

  1. c++虚函数_「C++」对象模型和虚函数
  2. 遇见你们,真好 ---致我的舍友
  3. 51单片机c语言测距,求助 关于C51单片机超声波测距 C语言程序设计 高手帮帮忙...
  4. IPFS(星际文件系统)的安装与使用
  5. 合并石子 区间dp水题
  6. JAVA进阶教学之(StringBuider进行字符串拼接)
  7. 五角星是不是旋转对称图形_新部编二年级下册数学第10单元总复习教案,克和千克、图形的运动...
  8. php 参数类对象以及改变对象,php类和对象--重载
  9. C语言学习——if语句
  10. 2017年网易校招Java面试题
  11. 打开conda环境报错:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x9a in position 317: illegal multibyt
  12. 关于breadcrumb面包屑
  13. [禅悟人生]有一种禅心叫认真
  14. (筆記) 否定疑問句的回答 (Japanese)
  15. 后台指标计算返回数据格式说明5 - DRAWTEXT_FIX格式
  16. 讲讲如何写论文和发论文(通信类)
  17. 数学和数学家的故事 zz
  18. 字符串处理函数C语言
  19. ef1a启动子_英茂盛业-EF1a启动子双标非融合慢病毒表达载体
  20. 阿里云服务器部署(新手福利)

热门文章

  1. radius认证服务器无响应 无法完成,客户端认证时提示radius server no response问题的解决方法...
  2. 云南白药产业环境分析
  3. 关于电脑电源选项,开合盖设置
  4. 一网友在上海的感受,太惊人的了,也太现实了,不得不看......
  5. Python列表及如何使用列表元素
  6. Field enhancement
  7. 阿里EasyExcel读写excel文件的基本使用
  8. [转自百度尘土飞扬博客]windows server 2003常用命令
  9. 安卓QQ闪照获取保存
  10. 求string字符串的长度