使用XPath解析XML文件
XPath是什么,简单的答案是用来手写XML解析的一种方法,复杂的答复就需要咨询一下Google,这里呢只记录一下使用方法,理论就不赘述了。
比如对于如下格式的XML文件,结构和内容并不复杂,直接使用DOM来手写解析过程倒也复杂,但是使用XPath的话,解析代码会更直接、更清晰一些。
import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.Reader;import javax.xml.xpath.XPath;import javax.xml.xpath.XPathConstants;import javax.xml.xpath.XPathFactory;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.InputSource;public class XPathTest { @SuppressWarnings("unchecked") public static void main(final String[] args) throws Exception { final File xmlFile = new File("a.xml"); final XPath xpath = XPathFactory.newInstance().newXPath();// 构建XPath解析对象 Reader reader = null; reader = new BufferedReader(new FileReader(xmlFile));// 构造文件IO输入对象,下面将提供文件IO对象给解析器 final NodeList nodes = (NodeList) xpath.evaluate("students/student", new InputSource(reader), XPathConstants.NODESET);// 使用XPath解析器,直接从XML信息中提取student节点的列表 for (int i = 0; i < nodes.getLength(); ++i) {// 遍历节点列表 final Node node = nodes.item(i); final Node nameNode = (Node) xpath.evaluate("name", node, XPathConstants.NODE);// 提取特定student节点下的name节点对应的XML对象,注意这里第二个参数是node,表达式为student的子节点name final String name = (String) xpath.evaluate("name", node, XPathConstants.STRING);// 提取特定student节点下name节点的值,注意第三个参数是字符串类型 System.out.println(nameNode.getNodeName() + " = " + name); final NamedNodeMap attrs = nameNode.getAttributes();// 提取name节点的属性列表对象 for (int j = 0; j < attrs.getLength(); ++j) { final Node attr = attrs.item(j); System.out.println(attr.getNodeName() + " = " + attr.getNodeValue());// 访问属性的值 } } if (reader != null) { reader.close(); } }}
日前在参加公司内部组织考试的时候,因为当时处于项目尾期,留给我准备的时间不多。等拿到考试题的时候发现题目要求解析一个XML文件,并对XML文件的格式做校验,并且不允许使用第三方库;这时有点傻眼,毕竟有好几年没有手写过XML解析代码,一下子竟完全想不起来解析器工厂如何初始化了。好在工作这么多年,心理素质还不错,没有被题目吓倒。突然想起来项目组同事前几天讨论的XPath技术,就抱着试试的想法在Java的文档中搜索类的文档,恰好找到了XPath相关的几个类,以及注释中的样例,于是考试题目顺利拿下。