在 java 中使用 dom4j 解析复杂xml文件

        在其实际应用中,有很多的方法读取xml配置文件,比如像dom,sax等等,但是它们有一个共同的缺点,就是对xml文件的读取操作太复杂。

        随着dom4j的出现另使用者眼前一亮,不仅仅是因为其API的支持,而且由于其对xml文件的节点操作更加的简单和方便。我们将在下面的代码中对使用dom或sax来获取节点的处理逻辑和使用dom4j获取节点的逻辑进行比较。来证明dom4j的读取xml的方便性和简洁性。这两种方法均使用同一个xml文件

请注意,本文不是坑,下面两种方法都可以成功解析xml文件,他们所用的xml文件均位于src文件下,如果要变换文件位置,请在代码里修改相应的位置即可。

下面是charCfg.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<parts>
	<part>
		<className>user</className>
		<attr>
			<name>sex</name>
			<properties>
				<property>
					<value>1</value>
					<lable>男</lable>
				</property>
				<property>
					<value>0</value>
					<lable>女</lable>
				</property>
				<property>
					<value>-1</value>
					<lable>未知</lable>
				</property>
			</properties>
		</attr>
	</part>
	<part>
		<className>message</className>
		<attr>
			<name>hasRead</name>
			<properties>
				<property>
					<value>1</value>
					<lable>已读</lable>
				</property>
				<property>
					<value>0</value>
					<lable>未读</lable>
				</property>
			</properties>
		</attr>
	</part>
</parts>

1.使用sax或dom读取xml文件

对应的java类为:

package testd;

import java.io.FileInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class TestProperties {
	private static final String[] KEYANDVALUE = { "value", "lable" };

	public static void main(String args[]) {
		try {
			String lableAndValue = getLableAndVal("user", "sex");
			System.out.println(lableAndValue);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static String getLableAndVal(String className, String attrbute)
			throws Exception {
		StringBuffer stringBuffer = new StringBuffer("{");
		DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();
		DocumentBuilder dombuilder = domfac.newDocumentBuilder();
		InputStream is = new FileInputStream("src/test1.xml");
		Document doc = dombuilder.parse(is);
		Element root = doc.getDocumentElement();
		// 得到根节点的子节点
		NodeList parts = root.getElementsByTagName("part"); // root是parts
		part: for (int i = 0; i < parts.getLength(); i++) {
			Node part = parts.item(i); // part
			if (part.getNodeType() != Node.ELEMENT_NODE) {
				continue part;
			}

			NodeList allClassList = part.getChildNodes();
			classAndAttr: for (int j = 0; j < allClassList.getLength(); j++) {
				Node classNode = allClassList.item(j);
				if (classNode.getNodeType() != Node.ELEMENT_NODE) {
					continue classAndAttr;
				}

				String className1 = classNode.getFirstChild().getNodeValue();
				if (!className.trim().equals(className1.trim())) {
					continue part;
				}
				Node attr = classNode.getNextSibling(); // attr
				attri: while (attr != null) {
					if (attr instanceof Element) {
						NodeList colums = attr.getChildNodes(); // attr下所有子节点集合
						d: for (int m = 0; m < colums.getLength(); m++) {
							Node columNode = colums.item(m); // attr下的每个子节点
							if (columNode.getNodeType() != Node.ELEMENT_NODE) {
								continue;
							}
							String coluName = columNode.getFirstChild()
									.getNodeValue();
							if (!coluName.trim().equals(attrbute.trim())) {
								attr = attr.getNextSibling();
								continue attri;
							}
							Node proNode = columNode.getNextSibling(); // property节点
							while (proNode.getNodeType() != Node.ELEMENT_NODE) {
								proNode = proNode.getNextSibling();
							}
							NodeList propertyList = proNode.getChildNodes();
							for (int n = 0; n < propertyList.getLength(); n++) {
								Node tempNode = propertyList.item(n);
								if (tempNode.getNodeType() != Node.ELEMENT_NODE) {
									continue;
								}
								NodeList keyAndValueList = tempNode
										.getChildNodes();
								for (int h = 0; h < keyAndValueList.getLength(); h++) {
									Node temp3 = keyAndValueList.item(h);
									if (temp3.getNodeName() == KEYANDVALUE[0]) {
										stringBuffer
												.append("\"")
												.append(temp3.getFirstChild()
														.getNodeValue())
												.append("\":");
									}
									if (temp3.getNodeName() == KEYANDVALUE[1]) {
										stringBuffer
												.append("\"")
												.append(temp3.getFirstChild()
														.getNodeValue())
												.append("\",");
										break;
									}
								}
							}
							String endString = stringBuffer.substring(0,
									stringBuffer.length() - 1) + "}";
							return endString;

						}
					}
					attr = attr.getNextSibling();

				}

			}

		}
		return null;
	}

}

根据上述代码,即可实现复杂的xml文件内容的读取,最终生成一个如下形式的字符串返回给main函数。

{"1":"男","0":"女","-1":"未知"}

2.使用dom4j读取xml文件

java文件如下:

package zuccess.zcplt.basic.advanced.util;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class CharConfigUtil {

	private static final String[] KEYANDVALUE = { "parts", "part", "className",
			"attr", "name", "properties", "property", "value", "lable" };

	public static void main(String[] args) {
		try {
			String returnValue = getLableAndVal("user", "sex");
			System.out.println(returnValue);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public static String getLableAndVal(String className, String attrbute)
			throws Exception {

		StringBuffer stringBuffer = new StringBuffer("{");
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("src/charCfg.xml"));
		Element root = document.getRootElement();
		List<Element> childrList = root.elements(KEYANDVALUE[1]);
		classTrav: for (Element element : childrList) {
			String classNameTemp = element.element(KEYANDVALUE[2]).getText();
			if (!className.trim().equals(classNameTemp.trim())) {
				continue classTrav;
			}
			List<Element> attrChildList = element.elements(KEYANDVALUE[3]);
			attrTrav: for (Element attrElement : attrChildList) {
				String columNam = attrElement.element(KEYANDVALUE[4]).getText();
				if (!attrbute.trim().equals(columNam.trim())) {
					continue attrTrav;
				}
				Element allProperties = attrElement.element(KEYANDVALUE[5]);
				List<Element> properties = allProperties
						.elements(KEYANDVALUE[6]);
				for (Element property : properties) {
					stringBuffer
							.append("\"")
							.append(property.element(KEYANDVALUE[7]).getText()
									.trim()).append("\":");
					stringBuffer
							.append("\"")
							.append(property.element(KEYANDVALUE[8]).getText()
									.trim()).append("\",");
				}
				String endString = stringBuffer.substring(0,
						stringBuffer.length() - 1).trim()
						+ "}";
				return endString;

			}
		}

		return null;
	}
}

上述代码同样可以实现返回如下的字符串给main函数

{"1":"男","0":"女","-1":"未知"}

比较上述两种读取方式可以发现,dom4j的代码量大大减少,逻辑清晰,代码易懂,获取节点方便。

你可能感兴趣的:(java解析xml文件,复杂xml文件解析,dom4j读取xml文件,sax读取xm文件)