配置XML文件能实现一些非常实用的功能,自然XML文件的解析工作必不可少。通过JDK内的API就可以完成XML文件的解析,把这一解析过程工具化,我们以后需要解析XML文件时,就不必写大量重复性的代码了。
下面给出了XML工具的实现类,如果是初学者,建议看不懂的地方当成是“巫师的咒语“,执行拿来主义,先学会用,日后再做理解。代码如下:
import java.io.IOException;
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.NodeList;
import org.xml.sax.SAXException;
public abstract class XMLParser {
/*
* 当需要解析多个XML文件时,则需要多次在DocumentBuilder工厂里取得它的实例,
* 实际上这一过程比较耗费时间,占用了珍贵的系统资源,且没有必要。
* 所以,把这一过程做成单例模式,并用static修饰DocumentBuilder的实例。
* 这样,无论实例化多少次XMLParser类,仅在第一次时取得DocumentBuilder的实例。
*/
private static DocumentBuilder db;
public XMLParser() {
}
//实现单例模式;
private static void init() {
if(db == null) {
try {
db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
System.out.println("初始化DocumentBuilder出错!");
e.printStackTrace();
}
}
}
//无论怎样抽取,都要给出一个获取Document实例的方法;
public static Document openXML(String xmlPath) throws SAXException, IOException {
Document document = null;
init();
//获取XML文件输入流
InputStream is = Class.class.getResourceAsStream(xmlPath);
//通过DocumentBuilder获取Document实例
document = db.parse(is);
return document;
}
//上面方法的重载
public static Document openXML(InputStream is) {
init();
Document document = null;
try {
document = db.parse(is);
return document;
} catch (SAXException e) {
System.out.println("XML文件打开出错,检查路径:");
e.printStackTrace();
} catch (IOException e) {
System.out.println("XML文件打开出错,检查路径:");
e.printStackTrace();
}
return null;
}
/*
* 这个抽象方法由用户来实现,也就是让用户自己决定如何处理XML文件内的信息;
* 这个抽象方法可以说是点睛之笔,完美体现了应用抽象方法的好处;
* 作为初学者,很难想到使用抽象方法来实现。
*/
public abstract void parseElement (Element element, int index);
//循环解析标记节点内部的子节点信息,并调用抽象方法,将信息交给用户处理;
public void parseTag(Document document, String tagName) {
NodeList nodeList = document.getElementsByTagName(tagName);
for (int index = 0;index < nodeList.getLength(); index++) {
Element node = (Element) nodeList.item(index);
parseElement(node, index);
}
}
//如果子节点内部还有子节点,就将该子节点作为标记节点,循环解析其子节点的信息;
public void parseTag(Element element, String tagName) {
NodeList nodeList = element.getElementsByTagName(tagName);
for (int index = 0;index < nodeList.getLength(); index++) {
Element node = (Element) nodeList.item(index);
parseElement(node, index);
}
}
}
下面是工具的使用方法:
import java.io.InputStream;
import org.w3c.dom.Element;
import PropertiesAndXML.XMLParser;
public class XMLParserDemo {
public static void main(String[] args) {
InputStream is = XMLParserDemo.class.getResourceAsStream("/userMethod.xml");
//通过创建匿名内部类的方式使用
new XMLParser() {
@Override
public void parseElement(Element element, int index) {
String name = element.getAttribute("actionName");
System.out.println(name);
}
}.parseTag(XMLParser.openXML(is), "action");
}
}
结合XML解析工具的实现浅谈工具开发思想。
XML文件解析,顾名思义,就是要取得XML文件中的信息。取得信息后,或是用来赋值操作,亦或是用来判断,这都与我们的工具无关了。所以,在开发工具之前,我们首先要明确哪些功能是我们工具应该实现的,哪些功能是不归我们工具管的。只有在合理的取舍后,我们所实现的工具才是有实用价值的。个人觉得,一个好的工具应该是这样的,提供必要的简单功能,具有普适性,复杂功能可由单一的功能组合而成。并且工具内部不实现复杂功能,使工具尽量“轻”。因为我们无法实现使用我们工具的人想要的全部功能,并且如果增加的复杂功能没有被使用,无形之中使我们的工具变得笨重不堪。这里我想到了X8086处理器与ARM处理器,其中X8086具有功能强大的复杂指令集,而ARM具有功能较少的精简指令集。X8086为了实现一些复杂功能,如将一块内存中的全部数据整体转移到另一块内存空间中,在电路层额外增加了一块电路,专门负责处理这一指令。每增加一个功能,就要额外增加一块电路,最终使得X8086处理器的主频卡在一个瓶颈高度,不能上提。但是可以发现,很多额外的功能,完全可以由用户编写的简单的指令组成的汇编程序完成,而这也就是ARM处理器的思想。集成了更少的电路,使ARM处理器的主频可以做到很高。主频的高度很大程度上决定了一个处理器运算速度的快慢,所以X8086被ARM超越。