package cn.lwuyang.xml.utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XmlUtils {
/**
* 将Element对象转换为Map集合
*
* 方法适用范围:适用于纯属性元素或者只包含只有文本的子元素
* 而类似<a><b><c>xxx</c></b></a>,此方法无法转换
* eg:
* <student number="N_1001">
* <name>zs</name>
* <age>23</age>
* <sex>male</sex>
* </student>
* -->>
* {number=N_1001, name=zs, age=23, sex=male}
*
* @param ele
* Element对象
* @return 返回Map集合
*
* @author liwuyang
*/
public static Map<String, String> element2Map(Element ele) {
//创建Map集合
Map<String, String> map = new LinkedHashMap<String,String>();
/**
* 遍历ele所有属性/所有子元素(前提是只是纯文本的内容的子元素:<a>liwuyang</a>),
* 并把遍历的结果添加到map集合中
*/
//遍历属性
List<Attribute> listAttrs = ele.attributes();
//属性名作键,属性值作值
for (Attribute attribute : listAttrs) {
map.put(attribute.getName(), attribute.getValue());
}
//遍历所有子元素
List<Element> listEles = ele.elements();
for (Element element : listEles) {
//判断当前的元素是否为纯文本元素
if(element.isTextOnly()){
//元素名做键,元素的文本内容作值
map.put(element.getName(), element.getText());
}
}
return map;
}
/**
* 将Map集合对象转换为Element对象
*
* Map对象: {number=N_1001, name=zs, age=23, sex=male}
*
* 1,元素名称我们不知道,键值对市属性还是元素我们也不知道,所以会有如下三种情况出现:
* a,键值对全部属性 <student number="N_1001" name="zs" age="23" sex="male"/>
* b,键值对全部是子元素
* <student>
* <number>N_1001</number>
* <name>zs</name>
* <age>23</age>
* <sex>male</sex>
* </student>
* c,键值对既有属性也子元素
* <student number="N_1003">
* <name>zs</name>
* ...
* <sex>male</sex>
* </student>
* -------
* 所以方法需要的参数为:
* 1,需要被转换的Map集合对象;
* 2,元素名称;
* 3,是添加属性还是添加元素,考虑到有多少子元素或者是属性,这里使用数组或者集合,因为我们不知道用户传递时数组还是集合
* 这里最好有方法的重载。包含在集合中的元素,统一添加为子元素
*
* {number=N_1001, name=zs, age=23, sex=male}.toElement(map, "student", [name, age, sex]);
*
*
* @param map 被转换的Map集合对象
* @param eleName 元素名称 eg. <student> ... </student>
* @param childs 制定的子元素
* @return 返回Element 对象
*
* @author liwuyang
*
*/
public static Element map2Element(Map<String, String> map, String eleName,
List<String> childs) {
Element ele = DocumentHelper.createElement(eleName);
//遍历map集合
for(String key : map.keySet()){
if(childs.contains(key)){
ele.addElement(key).setText(map.get(key));
}else{
ele.addAttribute(key, map.get(key));
}
}
return ele;
}
/**
* 将Map集合对象转换为Element对象
*
* @param map
* @param eleName
* @param childs
* @return
*
* @author liwuyang
*
*/
public static Element map2Element(Map<String, String> map, String eleName,
String... childs) {
// 将数组对象转换为集合
List<String> list = Arrays.asList(childs);
return map2Element(map, eleName, list);
}
/**
* 获取Document对象
*
* @param xmlName
* 获取的目标xml文件
* @return 返回document对象
*/
public static Document getDocument(String xmlName) {
return getDocument(xmlName, true);
}
/**
*
* 获取Document对象方法
*
* @param xmlName
* xml源文件
* @param relative
* 是否为相对路径
* @return Document对象
*
* @author liwuyang
*/
public static Document getDocument(String xmlName, boolean relative) {
if (relative) {
URL url = Thread.currentThread().getContextClassLoader()
.getResource(xmlName);
if (url == null) {
// 获取xml源文件路径
xmlName = Thread.currentThread().getContextClassLoader()
.getResource("").getPath()
+ xmlName;
} else {
xmlName = url.getPath();
}
}
// 创建xml解析器对象
SAXReader reader = new SAXReader();
try {
// 解析xml
return reader.read(xmlName);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
/**
*
* @param doc
* 需要保存的文档
* @param xmlName
* 目标文件
*
* @author liwuyang
*/
public static void saveDocument(Document doc, String xmlName) {
saveDocument(doc, xmlName, true);
}
/**
* DOM4J保存Document对象
*
* @param doc
* 需要保存的文档
* @param xmlName
* 目标文件
* @param relative
* 是否为相对路径
*
* @author liwuyang
*/
public static void saveDocument(Document doc, String xmlName,
boolean relative) {
// 创建XmlWriter输出流对象
XMLWriter xmlWriter = null;
/**
* OutputFormat 格式化器 参数1:String indent 缩进 参数2: boolean newlines 换行
*/
// 创建格式化器
OutputFormat format = new OutputFormat("\t", true);
// 去掉原有的空格
format.setTrimText(true);
// 获取文件路径
try {
if (relative) {
URL url = Thread.currentThread().getContextClassLoader()
.getResource(xmlName);
if (url == null) {
xmlName = Thread.currentThread().getContextClassLoader()
.getResource("").getPath()
+ xmlName;
}
}
// 创建字符输出流,设置编码为utf-8
Writer writer = new OutputStreamWriter(
new FileOutputStream(xmlName), "utf-8");
// 创建xml输出流
xmlWriter = new XMLWriter(writer, format);
// 执行写操作
xmlWriter.write(doc);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (xmlWriter != null) {
try {
xmlWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Do4j工具类第一个版本
最新推荐文章于 2023-11-04 01:10:01 发布