配置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超越。