DOM4j XML 工具类
之前项目有跟客户系统对接一个webservice系统,该接口有传参和返回都是xml,所以找时间百度研究了一下dom4j,dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。这里先分享下我项目中dom4j 工具类:
package com.blog.util; import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.lang.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; /**
*
* 描述 DOM4j XML 工具类
* @author 小当家
* @created 2017年8月16日
*/
public final class XmlUtil {
/**
* 使用的查询子孙节点的路径
*/
private static final String SELECT_PATH = ".//";
/**
* 默认编码
*/
private static final String DEFAULT_ENCODING = "UTF-8"; // Constructors
/** default constructor */
private XmlUtil() { } /**
*
* 描述 取得当前节点特定子节点的正文,只取第一个
* @author 小当家
* @created 2017年8月16日
* @param element 当前XML节点
* @param fieldCode 正文内容
* @return
*/
public static String getSonFieldContent(final Element element, final String fieldCode) {
if (element == null) {
return null;
} String content = null;
Element ele = element.element(fieldCode);
if (ele != null) {
content = ele.getText();
}
return content;
} /**
*
* 描述 取得当前节点特定子孙节点的正文,只取第一个
* @author 小当家
* @created 2017年8月16日
* @param element 操作的xml元素
* @param fieldCode 栏位名称
* @return
*/
public static Element getDesFieldElement(final Element element, final String fieldCode) {
Element tagertElement = null;
@SuppressWarnings("unchecked")
List<Element> list = element.selectNodes(SELECT_PATH + fieldCode);
if (list.size() > 0) {
tagertElement = list.get(0);
} return tagertElement;
} /**
*
* 描述 取得当前节点特定子孙节点的正文,只取第一个
* @author 小当家
* @created 2017年8月16日
* @param text 传入报文
* @param fieldCode 标签代码
* @return 标签内容
* @throws DocumentException
*/
public static String getDesFieldText(final String text, final String fieldCode) throws DocumentException {
Element rootEle = DocumentHelper.parseText(text).getRootElement();
Element desFieldEle = getDesFieldElement(rootEle, fieldCode);
if (desFieldEle != null) {
return desFieldEle.getText();
} else {
return null;
}
} /**
*
* 描述 取得当前节点特定子孙节点的正文,制定个数
* @author 小当家
* @created 2017年8月16日
* @param text 传入报文
* @param fieldCode 标签代码
* @param index 处理的元素索引
* @return 标签内容
* @throws DocumentException
*/
public static String getDesFieldTextByIndex(final String text, final String fieldCode, final int index)
throws DocumentException {
Element rootEle = DocumentHelper.parseText(text).getRootElement();
List<Element> eleList = (List<Element>) rootEle.selectNodes(SELECT_PATH + fieldCode);
if (eleList.size() > index) {
return eleList.get(index).getText();
} else {
return null;
} } /**
*
* 描述 取得子孙节点集合
* @author 小当家
* @created 2017年8月16日
* @param element 操作的xml元素
* @param fieldCode 栏位名称
* @return 正文内容
*/
@SuppressWarnings("unchecked")
public static List<Element> getDesFieldElementList(final Element element, final String fieldCode) {
return element.selectNodes(SELECT_PATH + fieldCode); } /**
*
* 描述 取得当前节点下所有拥有当前属性的元素
* @author 小当家
* @created 2017年8月16日
* @param element 当前元素
* @param fieldCode 查找属性名称
* @return
*/
public static List<Element> getEleListByAttr(final Element element, final String fieldCode) {
// 返回数据
List<Element> eleList = new ArrayList<Element>(); // 查找并循环添加
@SuppressWarnings("unchecked")
List<Attribute> attrList = element.selectNodes(SELECT_PATH + "@" + fieldCode);
for (Attribute attr : attrList) {
eleList.add(attr.getParent());
} // 返回
return eleList;
} /**
*
* 描述 取得当前节点下所有拥有当前属性的元素
* @author 小当家
* @created 2017年8月16日
* @param msgText 当前元素
* @param path 查找属性名称
* @return
*/
public static List<Element> getEleListByPath(final String msgText, final String path) {
// 返回数据
List<Element> eleList = new ArrayList<Element>(); try {
Document document;
document = DocumentHelper.parseText(msgText);
eleList = document.selectNodes(path);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 返回
return eleList;
} /**
*
* 描述 一次性增加多个子节点
* @author 小当家
* @created 2017年8月16日
* @param fatherEle 父亲节点
* @param sonEleList 要增加的子节点元素
*/
public static void addElements(final Element fatherEle, final List<Element> sonEleList) {
for (Element ele : sonEleList) {
fatherEle.add((Element) ele.clone());
}
} /**
*
* 描述 增加子元素
* @author 小当家
* @created 2017年8月16日
* @param fatherEle 父亲节点
* @param sonEleName 儿子节点名
* @param sonEleContent 儿子节点内容
* @return 儿子节点
*/
public static Element addElement(final Element fatherEle, final String sonEleName, final String sonEleContent) {
// 创建子节点
Element ele = DocumentHelper.createElement(sonEleName);
if (StringUtils.isNotBlank(sonEleContent)) {
ele.setText(sonEleContent);
} // 关联
fatherEle.add(ele); // 返回
return ele;
} /**
*
* 描述 最后最后一级的子节点,如果传入数据为空不增加
* @author 小当家
* @created 2017年8月16日
* @param fatherEle 父亲节点
* @param sonEleName
* @param sonEleContent
* @return
*/
public static Element addFinalSonElement(final Element fatherEle, final String sonEleName,
final String sonEleContent) {
// 创建子节点
Element ele = null; // 增加
if (StringUtils.isNotBlank(sonEleContent)) {
ele = DocumentHelper.createElement(sonEleName);
ele.setText(sonEleContent);
// 关联
fatherEle.add(ele);
} // 返回
return ele;
} /**
*
* 描述 取得XMl字符串中的指定路径字符
* @author 小当家
* @created 2017年8月16日
* @param text
* @param url
* @return
*/
public static String getUrlElementText(final String text, final String url) {
// 返回值
String resultText = null; // 转化XML
Element busiElement;
try {
busiElement = DocumentHelper.parseText(text).getRootElement();
List<Element> eleList = busiElement.selectNodes(url);
if (eleList.size() > 0) {
resultText = ((Element) busiElement.selectNodes(url).get(0)).getText();
}
} catch (DocumentException e) {
e.printStackTrace(); } // 返回
return resultText;
} /**
*
* 描述
* @author 小当家
* @created 2017年8月16日
* @param doc
* @param url
* @return
*/
public static String getUrlElementText(Document doc, final String url) {
Node node = doc.selectSingleNode(url);
if (node == null) {
return null;
}
return node.getText();
} /**
*
* 描述 格式化xml字符串
* @author 小当家
* @created 2017年8月16日
* @param xmlText xml字符串
* @return 格式化后的字符
* @throws Exception
*/
public static String formatXml(final String xmlText) throws Exception {
// 返回字符串
String reText; try {
reText = formatXml(xmlText, DEFAULT_ENCODING);
} catch (Exception e) {
throw new Exception(e.getMessage());
} // 返回
return reText;
} /**
*
* 描述 格式化xml字符串
* @author 小当家
* @created 2017年8月16日上午11:26:19
* @param xmlText xml字符串
* @param inEncoding 字符编码
* @return 格式化后的字符
* @throws Exception
*/
public static String formatXml(final String xmlText, final String inEncoding) throws Exception {
String encoding = inEncoding;
// 返回字符串
String reText; if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
} // 转化
try {
// 将字符串格式转换成document对象
Document document = DocumentHelper.parseText(xmlText); // 注意,用这种方式来创建指定格式的format
OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding(encoding); // 创建String输出流
StringWriter out = new StringWriter(); // 包装String流
XMLWriter writer = new XMLWriter(out, format); // 将当前的document对象写入底层流out中
writer.write(document);
writer.close();
reText = out.toString();
} catch (Exception e) {
String errTagMsg = "数据格式化失败!";
throw new Exception(errTagMsg);
} // 返回
return reText;
} /**
*
* 描述 复制XML元素的值到对应的对象属性当中
* @author 小当家
* @created 2017年8月16日
* @param obj 配置对象
* @param ele XML元素
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public static void copyEleToAttr(final Object obj, final Element ele)
throws IllegalArgumentException, IllegalAccessException, InstantiationException, ClassNotFoundException { // 获取f对象对应类中的所有属性域
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0, len = fields.length; i < len; i++) {
// 对于每个属性,获取属性名
String fieldName = fields[i].getName();
fields[i].setAccessible(true);
/**
* String属性直接进行赋值,如果是复杂类,进行下一步赋值
*/
if (fields[i].getType().equals(String.class)) {
String eleContent = XmlUtil.getSonFieldContent(ele, fieldName);
if (eleContent != null && !eleContent.equals("")) {
fields[i].set(obj, eleContent);
}
} else if (fields[i].getType().equals(List.class)) {
String eleName = fieldName.substring(0, fieldName.length() - 4);
List<Element> eleList = ele.elements(eleName);
List<Object> field = (List<Object>) fields[i].get(obj); // 取得泛型类型
Type fc = fields[i].getGenericType();
ParameterizedType pt = (ParameterizedType) fc;
Class driveClass = (Class) pt.getActualTypeArguments()[0];
try {
for (Element singleEle : eleList) {
Object singObjct = driveClass.newInstance();
// 判断是否是字符串
if (driveClass.equals(String.class)) {
singObjct = singleEle.getText(); } else {
copyEleToAttr(singObjct, singleEle);
}
field.add(singObjct);
}
} catch (Exception e) {
for (Element singleEle : eleList) {
String eleContent = singleEle.getTextTrim();
if (eleContent != null && !eleContent.equals("")) {
field.add(eleContent);
}
}
} } else {
Object fieldObject = fields[i].get(obj);
Element fieldEle = ele.element(fieldName);
if (fieldObject != null && fieldEle != null) {
copyEleToAttr(fieldObject, fieldEle);
}
}
}
} /**
*
* 描述 复制对应的对象属性当到XML元素的值中
* @author 小当家
* @created 2017年8月16日
* @param obj 配置对象
* @param ele XML元素
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@SuppressWarnings("unchecked")
public static void copyAttrToEle(final Object obj, final Element ele)
throws IllegalArgumentException, IllegalAccessException { // 获取f对象对应类中的所有属性域
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0, len = fields.length; i < len; i++) {
// 对于每个属性,获取属性名
String fieldName = fields[i].getName();
fields[i].setAccessible(true); // 过滤不处理的对象
if (Modifier.isStatic(fields[i].getModifiers())) {
continue;
} /**
* String属性直接进行赋值,如果是复杂类,进行下一步赋值
*/
if (fields[i].getType().equals(String.class)) {
XmlUtil.addFinalSonElement(ele, fieldName, (String) fields[i].get(obj));
} else if (fields[i].getType().equals(List.class)) {
List<Object> fieldList = (List<Object>) fields[i].get(obj);
for (Object object : fieldList) {
if (object.getClass().equals(String.class)) {
XmlUtil.addElement(ele, fieldName, (String) object);
} else {
copyAttrToEle(object, XmlUtil.addElement(ele, fieldName, null));
}
}
} else {
Object fieldObject = fields[i].get(obj);
if (fieldObject != null) {
Element fieldEle = XmlUtil.addElement(ele, fieldName, null);
copyAttrToEle(fields[i].get(obj), fieldEle);
}
}
} } }
DOM4j XML 工具类的更多相关文章
- XML工具类 - XmlUtils.java
XML工具类,提供序列化XML.反序列化XML.获取指定节点的值的方法. 源码如下:(点击下载 - XmlUtils.java.dom4j-1.6.1.jar.xstream-1.4.7.jar ) ...
- Java常用工具类---XML工具类、数据验证工具类
package com.jarvis.base.util; import java.io.File;import java.io.FileWriter;import java.io.IOExcepti ...
- JaxbUtil转json转XML工具类
json转换为XML工具类 package com.cxf.value; import org.springframework.util.StringUtils; import javax.xml.b ...
- android 解析XML 工具类
/** * Created by John on 2016/3/29. */ public class XmlParser { private static final String ns = nul ...
- xml转对象,对象转xml工具类
package com.dq.schooldomain.utils; import com.thoughtworks.xstream.XStream; import com.thoughtworks. ...
- jaxb解析xml工具类
[quote]jaxb jdk 自带的解析xml的一种方式支持,只需要用注解对javabean进行数据绑定[/quote] package com.nnk.flowrecharge.common;im ...
- 【java工具类】java做的一个xml转Excel工具,基于maven工程
说明:适合数据库导出为xml时转成Excel 本工具将上传至GitHub:https://github.com/xiaostudy/xiaostudyAPI3 doc4j的maven依赖 <!- ...
- Java工具类——通过配置XML验证Map
Java工具类--通过配置XML验证Map 背景 在JavaWeb项目中,接收前端过来的参数时通常是使用我们的实体类进行接收的.但是呢,我们不能去决定已经搭建好的框架是怎么样的,在我接触的框架中有一种 ...
- xml和map互转工具类
/** * xml转map工具类 * @author zhangyao * */ public class XmlToMapUtil { /** * xml转map 不带属性 * @param xml ...
随机推荐
- django中配置使用celery
环境版本: windows7 x64 django 1.11.6 django-celery 3.2.2 工程结构说明:源码下载请访问https://i.cnblogs.com/Files.aspx ...
- 【转】用 async/await 来处理异步
原文地址:https://www.cnblogs.com/SamWeb/p/8417940.html 昨天看了一篇vue的教程,作者用async/ await来发送异步请求,从服务端获取数据,代码很简 ...
- [转帖]Linux chattr 命令详解
Linux chattr 命令详解 https://www.cnblogs.com/ftl1012/p/chattr.html 常见命令参数 1 2 3 4 5 6 7 8 9 10 11 12 A: ...
- Java的常用API之System类简介
Syetem类 java.lang.System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用的方法有: public static long c ...
- IDEA开发React环境配置
概述 习惯了IDEA写代码,也不想在下一个webstorm,而且IDEA是webstorm的父集,webstorm能干的,IDEA应该也是可以的.本篇随便记录下idea下的react的环境搭建. 环境 ...
- Kafka MirrorMaker 跨集群同步工具
一.MirrorMaker介绍 MirrorMaker是Kafka附带的一个用于在Kafka集群之间制作镜像数据的工具.该工具从源集群中消费并生产到目标群集.这种镜像的常见用例是在另一个数据中心提供副 ...
- Entity Framework Core今日所得:避免 IEnumerable 以及 IQueryable 陷阱
避免 IEnumerable 以及 IQueryable 陷阱: IEnumerable示用Linq会先去数据库查询所有记录,然后再条件查询. IQueryable接口派生自IEnumerable,但 ...
- prometheus消耗内存问题
参考: https://stackoverflow.com/questions/56115912/why-does-prometheus-consume-so-much-memory https:// ...
- 坑人的Mysql5.7 (默认不支持Group By语句)(转)
部署项目时,项目启动完毕.点击有group by 查询语句时出现错误,界面中没有该有的数据.查询log日志发现错误 Expression #1 of SELECT list is not in GRO ...
- 【转载】C#中AddRange方法往ArrayList集合末尾添加另一个集合
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,如果需要往一 ...