XML解析:使用DOM4j解析xml文件

当前环境:dom4j 1.6.1

1.简介

dom4j一个简洁高效的xml解析工具

2.创建当前的users.xml文件用于解析


<users>
	<user isleaf="no">
		<username>adminusername>
		<age>18age>
		<onWork>trueonWork>
	user>
	<user isleaf="yes">
		<username>guestusername>
		<age>20age>
		<onWork>falseonWork>
	user>
users>

3.查找dom4j可以解析xml的类

1.查看当前的源码查找可用的dom4j的加载当前xml文件
XML解析:使用DOM4j解析xml文件_第1张图片
通过源码发现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;
    }

4.使用dom4j开始解析

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方法直接定位到需要的标签的属性,简单又强大

5.结果

XML解析:使用DOM4j解析xml文件_第2张图片

6.扩展使用当前的dom4j加载并初始化类

当前的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;
	}

}

由于这里使用了工具,都是自己写的这里就不显示了,主要使用了反射

结果:
XML解析:使用DOM4j解析xml文件_第3张图片

7.总结

1.dom4j用来解析当前的xml真的很方便

2.使用dom4j进行解析的时候需要使用w3c的document对象转换为dom4j的document对象

3.注意在使用反射进行赋值的时候需要注意权限的问题

以上纯属个人见解,如有问题请联系本人!

你可能感兴趣的:(Java工具)