在网上search了很多DOM解析XML的代码,总觉得不好,主要原因是都有这样的代码:
document.getElementsByTagName("tagName");
我希望能有一个对XML标签名没有限定的处理逻辑,只需要传入XML文件的路径,即可对此XML进行解析。一直找不到,就自己手写了一个。
DOM解析有三点是很重要的,可能我的描述并不准确,因为我是在debug过程中分析出来的,并没有去参看DOM的文档。
- DOM将回车(换行符)和节点内容(Value)都是作为节点来解析的。
- 因为第一点,DOM将节点进行了分类,主要是有两类:TEXT_NODE ,ELEMENT_NODE,通过对节点的类型判断,可以很好的解析和过滤所有的节点。
- DOM在获取TETX_NODE类型的节点的内容时,如果是回车(换行符),解析后的内容是由一个或多个的"\n","\t"组成的字符串,而内容(Value)节点解析后的则就是其值,不含"\n","\t"。
明白了这三点就可以很容易的对XML进行解析。
此代码适用于各种XML的格式,直排,竖排,乱排。
注意:XML的排版方式不同,解析效果是不一样的,此代码适用任意的排版方式
OK,上代码:
package ryan.xiao.javaSE.OOP;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
public class XMLDemo1 {
public static void main(String args[]) throws ParserConfigurationException, SAXException, IOException{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(new File("E:" + File.separator+ "java3" + File.separator + "XMLTest" + File.separator
+ "test.xml"));
NodeList nodeList = document.getChildNodes(); //只有一个元素,且是根节点
NodeList rootNodeList = nodeList.item(0).getChildNodes(); //得到根节点下所有的第一级子节点
fun(rootNodeList);
}
/**
* 解析方法,传递一个NodeList进去
* @param document
*/
private static void fun(NodeList nodeList) {
for (int i = 0; i < nodeList.getLength(); i++) {
Node nodeTemp = nodeList.item(i);
if(nodeTemp.hasAttributes()){
NamedNodeMap nodeAttrList = nodeTemp.getAttributes(); //获得node的属性
for(int j = 0;j<nodeAttrList.getLength();j++){
Node nodeAttr = nodeAttrList.item(j);
System.out.print(nodeTemp.getNodeName()+ "节点有属性:");
System.out.println(nodeAttr);
System.out.println("属性值为:" + nodeAttr.getNodeValue());
}
}
short typeTemp = nodeTemp.getNodeType();
if (typeTemp == 1) { // 是"ELEMENT_NODE"
if (nodeTemp.hasChildNodes()) { // 如果此元素节点还有子节点
fun(nodeTemp.getChildNodes());
} else {
// 无子节点,表示此节点中无内容类似于:<item></item>
System.out.println("此节点无内容" + nodeTemp.getNodeName());
}
} else { // 是换行或是内容节点
String str = nodeTemp.getTextContent().replace("\n", "");
str = str.replace("\t", "");
if (!(str.equals(""))) { // 过滤有内容的节点
System.out.print(nodeTemp.getParentNode().getNodeName()+ ":");
System.out.println(nodeTemp.getNodeValue().trim());
}
}
}
}
}
<?xml version="1.0"?>
<info>
<item>
<image>assets/icons/bi.jpg</image>
</item>
<item>
<image>assets/icons/ai.jpg</image>
</item>
<item>
<image>assets/icons/ci.jpg</image>
</item>
<item>
<image>assets/icons/fw.jpg</image>
</item>
<item>
<image>assets/icons/ew.jpg</image>
</item>
<item>
<image>assets/icons/air.jpg</image>
</item>
</info>