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 ...
随机推荐
- UI自动化实例:遍历点击带有滚动条的列表每一项
需求:验证列表每条资讯里的用户数是否正确.该列表分页请求数据,每页10条,每次滚动到底部自动增量请求10条. 实现自动化必要性: 1 资讯每天不定时更新需经常性验证, 程序更新或者环境切换需验证所有资 ...
- Source Insight添加新的文件类型
1.前言 Source Insight这个软件工具功能非常强大,很适合用来分析一些大型的code工程,例如Linux内核源码,本文将简单介绍如何在Source Insight工程中添加一种新的文件类型 ...
- AKKA Router路由
路由概念 大量的actor在并行工作的时候,处理到来的消息流,这时候就需要一个组件或者东西来引导消息从源到目的地Actor,这个组件或者东西就是Router在Akka中,router也是一种actor ...
- BZOJ3926 ZJOI2015诸神眷顾的幻想乡(广义后缀自动机)
对多串建立SAM的一种方法是建trie再对trie建SAM.构造方式分为在线(也即不建trie而是依次插入每个串,或在trie上dfs)和离线(也即建好trie再bfs).其中离线构造与单串的构造方式 ...
- java运算符的优先级别
一.运算符的优先级 运算符按照优先级别的高低排序分别是:自加/减运算符. 算术运算符.比较运算符.逻辑运算符.赋值运算符.具体请参考下表: 顺序 运算符 1. 括号,如 ( ) 和 [ ] 2. 一元 ...
- Entity Framework 学习系列(3) - MySql Code First 开发方式+数据迁移
目录 # 写在前面 一.开发环境 二.创建项目 三.安装程序包 四.创建模型 五.连接字符串 六.编辑程序 七.数据迁移 写在最后 # 写在前面 这几天,一直都在学习Entity Framework ...
- J2EE 练习题 - JSON HTTP Service
J2EE 练习题 - JSON HTTP Service 1 要求 2 示例代码 2.1 Server 端 2.2 客户端 - Java 1 要求 在 Tomcat 上布署一个 HTTP Servic ...
- mvc_1_ex_stu_manage
Mvc第一遍结束综合练习:带权限的学生管理系统程序的设计应该根据功能来进行.先来设想一下本练习的程序功能:学生信息管理.登录用户区分权限.出错应该给出提示.由此可以设想,完成以后的程序是下图的样子:主 ...
- 如何在JIRA中有效使用关注和@提及 我正在关注的问题 提及我的问题 在仪表板上显示
如何在JIRA中有效使用关注和@提及http://bbs.51testing.com/forum.php?mod=viewthread&tid=1157043&fromuid=1530 ...
- JS面向对象设计-理解对象
不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念, 它把对象定义为"无序属性(基本值.对象.函数)的集合",类似于散列表. 每 ...