要处理xml文件,就要先解析他,解析器是这样工作的,他读入一个文件,确认这个文件具有正确的格式,然后将其分解成各种元素,使得程序员能够访问各个元素。
java提供了两种xml解析器:
1 DOM解析器(树形解析器)
2 SAX解析器(流机制解析器)
one by one 让我们先来学习DOM解析器
所谓树形解析器就是把xml文件的各个元素按照树形结构读入内存,如果是大型的xml文件,这对我们的内存也是一个相当大的考验。
<student id="138896"> <name>王五</name> <age>16</age> </student>着是一个简单的xml文件,让我们看看dom解析器读进内存是什么样子的:
好了,我们知道dom解析器是读入xml文件的格式了,我们可以大体上吧xml文件的内容分为下面的对象:
1 文档: Document对象
2 元素: Element对象
3 标签内容 :Text对象
4 属性:Attr对象
好了,那摩我们如何来得到解析器呢?下面的代码将会告诉我们:
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //通过工厂类的newInstance()函数创建DocumentBuilderFactory实例 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //创建DocumentBuilderFactory实例创建documentBuilder实例 Document document = documentBuilder.parse("src/day.xml"); //获得document对象 Node fElement = document.getDocumentElement();//获得根元素的Element对象我们可以通过根元素对象来遍历子元素实现xml文件的遍历,代码小施: public class JaxpTest { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //通过工厂类的newInstance()函数创建DocumentBuilderFactory实例 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //创建DocumentBuilderFactory实例创建documentBuilder实例 Document document = documentBuilder.parse("src/day.xml"); //获得document对象 Node fElement = document.getDocumentElement(); bianli(fElement); } public static void bianli(Node node) { if(node instanceof Element){ //判断获取的子元素是否是Element对象 Element element = (Element) node; //若果是我们就进行类型转换 System.out.print("<" + element.getTagName()); //打印开始标签名称 NamedNodeMap nNM = element.getAttributes(); //得到元素的属性对象集 for (int i = 0; i < nNM.getLength(); i++) { //遍历属性对象集并打印属性名和值 Attr attr = (Attr)nNM.item(i); System.out.print(" " + attr.getName() + "=\"" + attr.getValue() + "\""); } System.out.println(">"); NodeList nL = element.getChildNodes(); //获取子元素集 for(int i = 0;i < nL.getLength(); i++) { //遍历子元素 Node nNode = nL.item(i); bianli(nNode); //递归过程 } System.out.println("</" + element.getTagName() + ">"); //打印结束标签 } else if(node instanceof Text) { //如果得到的子元素是Text对象就对其内容进行输出 Text t = (Text) node; System.out.println(t.getData().trim()); //去除内容体中的空格 } } }好了,这就是dom解析器的大致操作,更多详细内容请自己查看API。那摩问题来了,这如果我们的xml文件相当的大而我们只需要查找里面的一少部分内容,但是这些内容对于一个树形结构来说又太深了,我们总不能一层一层的查找吧,这样的代码量反正我是写不下去。那摩我们想要偷懒就得使用XPath喽!
XPath是用来更好的查询xml标签的,他的具体使用可以参见网页文档,可以是中文的哦!
http://www.zvon.org/xxl/XPathTutorial/General_chi/examples.html 关于xpath的使用大致分这几个过程: 1 构建XPath工厂实例 2 通过XPath工厂构建XPath实例 3 利用实例的evaluate()方法来得到你想要的结果,这是一个重载方法: 详细情况可以参见api,下面是一个XPath使用的小应用: public class XpathTest { public static void main(String[] args) throws Exception { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();//获取xml文件解析器对象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();//获取文件解析器 Document doc = documentBuilder.parse("src/day.xml");//得到document对象 XPathFactory xPathFactory = XPathFactory.newInstance();//得到XPath工厂实例 XPath xp = xPathFactory.newXPath();//得到XPath实例 Node node = (Node) xp.evaluate("/class/student"/*XPath表达式*/, doc/*关于xml的四种对象*/,XPathConstants.NODE/*返回值类型*/);//利用XPath实例的evaluate方法来获取这个元素 if(node instanceof Node) { Element element = (Element)node; System.out.println(element.getTagName() + " id=\"" + element.getAttribute("id") + "\"");//得到该元素的属性 } } }好了我们学了dom解析器,是不是还有一个sax解析器,来吧!没办法硬着头皮学吧! sax解析器 和使用dom解析器一样我们得得到解析器的一个实例: 首先我们来讲解一下sax解析器的解析原理: 好了,明白了这个原理让我们来编写一个遍历xml文件的代码是不是更加简单! public class SaxXmlTest { public static void main(String[] args) throws Exception { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser saxParser = saxParserFactory.newSAXParser(); MyDH dh = new MyDH(); saxParser.parse("src/day.xml", dh); } } public class MyDH extends DefaultHandler{ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.print("<" + qName); if(attributes.getLength() != 0) { for(int i = 0;i < attributes.getLength();i++) { System.out.print(attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\""); } } System.out.println(">"); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("</" + qName + ">"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { for (int i = 0; i < length; i++) { char c = ch[start + i]; System.out.print(c); } System.out.println(); } } 但是我们不得不面对一个现实,那就是我们在实际开发中是不使用这两种方式的,但是我们为什么还来学习他们呢,注意我们学的只是他们的原理,其实其他的解析方式,也是根据这两个原理来的,所谓一法通,万法通,我们会了这两个,其他的也就差不多了。 我们在实际开发中使用的较为多的是dom4j,这个解析器我真的不想多说,就给个例子就行了,我们原理都会了,害怕他,开玩笑,万变不离其宗,只是方法名字不同而已。 package com.weijinhao.usedom4j; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Iterator; import java.util.List; import org.dom4j.Node; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /** * 其实使用dom4j和Java自带的解析器在表面操作上没有什么太大的区别,主要是底层实现的原理不相同,dom4j可以说是集成了dom和sax的 * 优点,即便于增删也便于查找,当然了,dom4j不是JavaSE的部分,所以我们必须得导包。 * 我们知道要想通过便捷查找就得使用XPath了,但是dom4j默认是不支持XPath的,我们需要导入其jar包。 * 在dom4j的lib文件夹中,名叫:jaxen-1.1-beta-6.jar * 并且使用doucment对象的document.selectSingleNode(arg0); * document.selectNodes(arg0);这两个函数来实现查找。 * 关于XPath的使用方法我们这就不都说了。 */ public class UseDom4J { public static void main(String[] args) throws Exception { //simpleUse(); //useXPath(); } public static void useXPath() throws DocumentException { File file = new File("E:/javajichu/usedom4j/one.xml"); SAXReader saxReader = new SAXReader();//创建解析器 Document document = saxReader.read(file);//获得doc对象 List <Node> ls = document.selectNodes("/school/class/student"); for (Node node : ls) { Element e = (Element)node; System.out.print(e.getName() + " "); List<Node> le = e.attributes(); for (Node attr : le) { System.out.print(attr.getName() + "=" + attr.getStringValue()); } System.out.println(); } } public static void simpleUse() throws DocumentException, UnsupportedEncodingException, FileNotFoundException, IOException { File file = new File("E:/javajichu/usedom4j/one.xml"); SAXReader saxReader = new SAXReader();//创建解析器 Document document = saxReader.read(file);//获得doc对象 Element rootElement = document.getRootElement(); Element clazz = rootElement.addElement("class"); clazz.addAttribute("num","计c133"); Element e1 = clazz.addElement("student"); e1.addAttribute("name","张三"); e1.addAttribute("num","138"); Element e2 = clazz.addElement("student"); e2.addAttribute("name","李思"); e2.addAttribute("num","137"); //我们用来获取输出的格式,这样的格式看起来更加友好 OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file), format); xmlWriter.write(document);//保存我们的修改 xmlWriter.close(); } }