当前环境:dom4j 1.6.1
dom4j一个简洁高效的xml解析工具
<users>
<user isleaf="no">
<username>adminusername>
<age>18age>
<onWork>trueonWork>
user>
<user isleaf="yes">
<username>guestusername>
<age>20age>
<onWork>falseonWork>
user>
users>
1.查看当前的源码查找可用的dom4j的加载当前xml文件
通过源码发现io包中有一个DOMReader可以用来加载当前的xml文件流
通过查看源码发现具有一个read方法加载Document对象,所以可以这样使用
public Document read(org.w3c.dom.Document domDocument) {
if (domDocument instanceof Document) {
return (Document) domDocument;
}
Document document = createDocument();
clearNamespaceStack();
org.w3c.dom.NodeList nodeList = domDocument.getChildNodes();
for (int i = 0, size = nodeList.getLength(); i < size; i++) {
readTree(nodeList.item(i), document);
}
return document;
}
public class DOM4JDemo {
@Test
public void test() throws SAXException, IOException, ParserConfigurationException, InstantiationException,
IllegalAccessException {
//加载当前资源下的文件
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("users.xml");
Document document = parseXml(is);
Element rootElement = getRootElement(document);
printAll(rootElement);
is.close();
}
public Document parseXml(InputStream is) throws SAXException, IOException, ParserConfigurationException {
//通过w3c标准的DocumentFactory以流的方式加载当前的xml文件
org.w3c.dom.Document domDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
DOMReader domReader = new DOMReader();
Document dom4jDocument = domReader.read(domDocument);
return dom4jDocument;
}
public Element getRootElement(Document doc) {
return doc.getRootElement();
}
//开始解析
public void printAll(Element rootElement)
throws InstantiationException, IllegalAccessException {
String rootElementName = rootElement.getName();
System.out.println("当前的根结点:"+rootElementName);
// 开始迭代当前的根结点
Iterator<?> nodeIterator = rootElement.nodeIterator();
while (nodeIterator.hasNext()) {
Object obj = nodeIterator.next();
// 如果获取的当前的元素为默认的结点元素
if (obj instanceof DefaultElement) {
DefaultElement next = (DefaultElement) obj;
// 输出当前结点迭代的名称
System.out.println("当前结点的名称:" + next.getName());
String username = next.elementText("username");
String age = next.elementText("age");
String onWork = next.elementText("onWork"); //
// 直接获取这个元素结点的属性
Attribute attribute = next.attribute("isleaf");
System.out.println("username:" + username);
System.out.println("age:" + age);
System.out.println("onWork:" + onWork);
System.out.println("attribute:" + attribute.getValue());
}
}
}
}
1.发现当前的Document为dom4j并且可以使用elementText方法直接获取结点中的文本内容,可以使用attribute方法直接定位到需要的标签的属性,简单又强大
当前的User类
public class User {
private String username;
private Integer age;
private Boolean onWork;
private String isleaf;
.... 省略getter、setter方法以及toString方法
}
2.开始编写使用的类
/**
* @description 自定义解析工具,用于解析当前的xml文件
* @author hy
* @date 2019-10-23
*/
public class MyDOM4JUtils {
@Test
public void test() throws SAXException, IOException, ParserConfigurationException, InstantiationException,
IllegalAccessException {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("users.xml");
Document document = parseXml(is);
Element rootElement = getRootElement(document);
List<User> parseToList = parseToList(rootElement, User.class);
System.out.println(parseToList);
is.close();
}
public Document parseXml(InputStream is) throws SAXException, IOException, ParserConfigurationException {
org.w3c.dom.Document domDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
DOMReader domReader = new DOMReader();
Document dom4jDocument = domReader.read(domDocument);
return dom4jDocument;
}
public Element getRootElement(Document doc) {
return doc.getRootElement();
}
public <T> List<T> parseToList(Element rootElement, Class<T> clazz)
throws InstantiationException, IllegalAccessException {
// 开始迭代当前的根结点
Iterator<?> nodeIterator = rootElement.nodeIterator();
List<T> datas = new ArrayList<T>();
while (nodeIterator.hasNext()) {
Object obj = nodeIterator.next();
// 如果获取的当前的元素为默认的结点元素
if (obj instanceof DefaultElement) {
DefaultElement next = (DefaultElement) obj;
// 输出当前结点迭代的名称
System.out.println("当前结点的名称:" + next.getName());
System.out.println(clazz.getName());
if (clazz.getName().toLowerCase().contains(next.getName().toLowerCase())) {
T instance= getInstance(clazz);
putObjectValue(instance, next);
datas.add(instance);
}
}
}
return datas;
}
//简单的类型转换
public Object convert(Object from,Class<?> to) {
String value=(String) from;
return ConvertUtils.convert(value, to);
}
//获取需要的值
public Object getByObjectNeedValue(DefaultElement next,String key) {
String elementText = next.elementText(key);
Object value=null;
if (elementText != null || !"".equals(elementText)) {
value = elementText;
}
Attribute attribute = next.attribute(key);
if(attribute!=null) {
value = attribute.getValue();
}
return value;
}
//向对象中放入值
public <T> void putObjectValue(Object target, DefaultElement next) {
Map<String, Field> filedMap = getFiledMap(target.getClass());
// 直接获取这个元素中的文本内容
for (String key : filedMap.keySet()) {
Field field = filedMap.get(key);
Object value = getByObjectNeedValue(next,key);
putFiledValue(field, target, value);
}
}
//获取对象的实例
public <T> T getInstance(Class<T> clazz) {
T newInstance = null;
try {
newInstance = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return newInstance;
}
// 开始像对象中设置值
public void putFiledValue(Field field, Object target, Object value) {
Object needValue=value;
try {
field.setAccessible(true);
needValue = convert(needValue,field.getType());
field.set(target, needValue);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 获取当前的类中的属性和方法
public Map<String, Field> getFiledMap(Class<?> clazz) {
Map<String, Field> filedMap = ReflectionUtils.getFiledMap(clazz);
return filedMap;
}
}
由于这里使用了工具,都是自己写的这里就不显示了,主要使用了反射
1.dom4j用来解析当前的xml真的很方便
2.使用dom4j进行解析的时候需要使用w3c的document对象
并转换为dom4j的document对象
3.注意在使用反射进行赋值的时候需要注意权限的问题
以上纯属个人见解,如有问题请联系本人!