使用DOM加载XML文件
在网上看了几篇关于java加载XML文件的做法,感觉都比较简单,对工具类的使用也比较少,刚好项目中碰到了加载XML的问题,在此记录以下。
XML文件样式
这个XML文件是有三层标签的,基本上业务不复杂就够用了。
<interface>
<!-- 运行状态 -->
<object nTypeId="802" cTypeId="8020000000119" pTypeId="4996" layer="LR_Encapsulation" layerParameter="OperateStatus">
<resource resType="OTN_A_PG8_PORT_CONFIG2" resProperty="ETH_LINK_STATUS" />
</object>
<!-- MAC地址 -->
<object nTypeId="802" cTypeId="8020000000119" pTypeId="4996" layerRate="LR_Ethernet" layerParameter="PhysAddress">
<resource resType="RCMACSEARCHSHOWTABLE" resProperty="MAC_ADDRESS" />
</object>
</interface>
java代码
代码只写了关键部分,主要是怎样加载XML文件以及解析xml,怎么提取配置的属性。至于怎么处理,根据具体业务具体分析。
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.springframework.stereotype.Component;
import org.w3c.dom.Attr;
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;
//使用ClassLoader加载XML文件进内存
private static URL getXmlFileURLByName(String fileName, ClassLoader classLoader) {
ClassLoader urlclassloader = classLoader;
URL url = urlclassloader.getResource(fileName);
if (url == null) {
log.error("Cannot find xml file [" + fileName + "].");
throw new NullPointerException();
}
return url;
}
//将XML解析成Document对象
private static Document parseXml2Document(@NotNull URL url) {
DocumentBuilderFactory documentbuilderfactory = DocumentBuilderFactory.newInstance();
documentbuilderfactory.setNamespaceAware(true);
documentbuilderfactory.setCoalescing(true);
try {
DocumentBuilder documentbuilder = documentbuilderfactory.newDocumentBuilder();
return documentbuilder.parse(url.openStream());
} catch (SAXException | IOException | ParserConfigurationException e) {
log.error("Fail to decode the file : " + url.toString() + " , the exception is : " + e.getMessage());
}
return null;
}
//Document对象是一个树结构,类似于前端里说的dom树,我们首先要做的事取到根节点。
String filePath = "XML路径";‘
//classLoader有很多获取方式,任意都可以。
ClassLoader classLoader = this.getClass().getClassLoader();
URL url = getXmlFileURLByName(filePath, classLoader);
Document doc = parseXml2Document(url);
//获取根节点
if (doc != null) {
Node node = doc.getDocumentElement();
}
//注意,下面都是核心操作代码,关于如何取属性的,业务不相干。都是一些散的代码。可能有些{}对不上
//node是根节点(interface),获取它的所有子节点
if(node.hasChildNodes()) {
NodeList nodeList = node.getChildNodes();
for(int i=0, len=nodeList.getLength(); i < len; ++i) {
//<object>节点
Node childNode = nodeList.item(i);
//这是dom自定义的,用于判断是不是一个元素类型的。getNodeName()可以获取节点名“object”
short nodeType = childNode.getNodeType();
if(nodeType == Node.ELEMENT_NODE && childNode.getNodeName().equalsIgnoreCase("object")) {
// read object获取此标签中的属性
NamedNodeMap namednodemap = childNode.getAttributes();
if (namednodemap != null) {
for (int i = 0, len=namednodemap.getLength(); i < len; ++i) {
Attr attr = (Attr) namednodemap.item(i);
if(attr.getNodeName().equalsIgnoreCase("nTypeId")) {
nTypeId = attr.getNodeValue();
}else if(attr.getNodeName().equalsIgnoreCase("cTypeId")) {
cTypeId = attr.getNodeValue();
}else if(attr.getNodeName().equalsIgnoreCase("pTypeId")){
pTypeId = attr.getNodeValue();
}else if(attr.getNodeName().equalsIgnoreCase("layer")){
layer = attr.getNodeValue();
}else if(attr.getNodeName().equalsIgnoreCase("layerParameter")){
layerParameter = attr.getNodeValue();
}
}
}
// read resource获得<resource>里面的属性
if (node.hasChildNodes()) {
NodeList nodeList = node.getChildNodes();
for(int k=0, listLen=nodeList.getLength(); k < listLen; ++k) {
Node childNode = nodeList.item(k);
short nodeType = childNode.getNodeType();
if(nodeType == Node.ELEMENT_NODE && childNode.getNodeName().equalsIgnoreCase("resource")) {
NamedNodeMap childnodemap = childNode.getAttributes();
if (childnodemap != null) {
for (int j = 0, len=childnodemap.getLength(); j < len; ++j) {
Attr attr = (Attr) childnodemap.item(j);
if(attr.getNodeName().equalsIgnoreCase("resType")) {
resType = attr.getNodeValue();
}else if(attr.getNodeName().equalsIgnoreCase("resProperty")) {
resProperty = attr.getNodeValue();
}
}
}
break;
}
}
}
}
}
}