在其实际应用中,有很多的方法读取xml配置文件,比如像dom,sax等等,但是它们有一个共同的缺点,就是对xml文件的读取操作太复杂。
随着dom4j的出现另使用者眼前一亮,不仅仅是因为其API的支持,而且由于其对xml文件的节点操作更加的简单和方便。我们将在下面的代码中对使用dom或sax来获取节点的处理逻辑和使用dom4j获取节点的逻辑进行比较。来证明dom4j的读取xml的方便性和简洁性。这两种方法均使用同一个xml文件
请注意,本文不是坑,下面两种方法都可以成功解析xml文件,他们所用的xml文件均位于src文件下,如果要变换文件位置,请在代码里修改相应的位置即可。
下面是charCfg.xml文件
user
sex
1
男
0
女
-1
未知
message
hasRead
1
已读
0
未读
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
Node part = parts.item(i); // part
if (part.getNodeType() != Node.ELEMENT_NODE) {
continue part;
}
NodeList allClassList = part.getChildNodes();
classAndAttr: for (int j = 0; 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
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
Node tempNode = propertyList.item(n);
if (tempNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}
NodeList keyAndValueList = tempNode
.getChildNodes();
for (int h = 0; 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 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 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 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的代码量大大减少,逻辑清晰,代码易懂,获取节点方便。