XML优点:平台无关性,语言无关性,系统无关性
XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析.假设我们XML的内容和结构如下:
<?xml version="1.0" encoding="UTF-8"?> <employees> <employee> <name>Darren</name> <sex>man</sex> <age>25</age> </employee> </employees>下面是解析XMl常用的Dom和Sex方法:
package com.darren.test.xml; public interface XmlParse { void createXml(String path); void parseXml(String path); }
1、DOM生成和解析XML文档
为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)。
package com.darren.test.xml; import java.io.FileOutputStream; import java.io.PrintWriter; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DomParse implements XmlParse { private static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @Override public void createXml(String path) { try { DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); // 创建根节点 Element root = document.createElement("employees"); // 添加根节点 document.appendChild(root); // 创建一级子节点 Element employee = document.createElement("employee"); // 操作一 // 创建二级子节点 Element name = document.createElement("name"); // 为二级子节点添加值 name.appendChild(document.createTextNode("Darren")); // 把二级子节点放到一级子节点下 employee.appendChild(name); // 同操作一 Element sex = document.createElement("sex"); sex.appendChild(document.createTextNode("man")); employee.appendChild(sex); // 同操作一 Element age = document.createElement("age"); age.appendChild(document.createTextNode("25")); employee.appendChild(age); // 把一级子节点添加到根节点下 root.appendChild(employee); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(document); transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT,"yes"); PrintWriter pw = new PrintWriter(new FileOutputStream(path)); StreamResult result = new StreamResult(pw); transformer.transform(source,result); System.out.println("生成XML文件成功!"); } catch (Exception e) { e.printStackTrace(); } } @Override public void parseXml(String path) { try { DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(path); Element root = document.getDocumentElement(); NodeList employee = root.getChildNodes(); outPut(employee); System.out.println("解析XML文件成功!"); } catch (Exception e) { e.printStackTrace(); } } private void outPut(NodeList nodeList) { int length = nodeList.getLength(); for (int i = 0; i < length; i++) { Node node = nodeList.item(i); // 叶子节点 if (node.getChildNodes().getLength() == 1) { String nodeName = node.getNodeName(); String nodeValue = node.getTextContent(); System.out.println(nodeName + ":" + nodeValue); } // 非叶子节点 if (node.getChildNodes().getLength() > 1) { NodeList subList = node.getChildNodes(); outPut(subList); } } } }
打印结果:
生成XML文件成功! name:Darren sex:man age:25 解析XML文件成功!
2、SAX生成和解析XML文档
为解决DOM的问题,出现了SAX。SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
优点:不用事先调入整个文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;
package com.darren.test.xml; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MySAXHandler extends DefaultHandler { // 一般将正式解析前的一些初始化工作放到这里面 public void startDocument() throws SAXException { System.out.println("文档开始打印了"); } // 收尾工作放在endDocument中 public void endDocument() throws SAXException { System.out.println("文档打印结束了"); } // XML解析器遇到XML里面的tag时就会调用这个函数。经常在这个函数内是通过qName俩进行判断而操作一些数据 public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException { if (qName.equals("employees")) { return; } if (qName.equals("employee")) { return; } System.out.print(qName + ":"); } // 这个方法与startElement()相对应,解析完一个tag节点后,执行这个方法 public void endElement(String uri,String qName) throws SAXException { } // 回调方法。解析器执行完startElement()后,解析完节点的内容后就会执行这个方法,并且参数ch[]就是节点的内容 public void characters(char[] ch,int start,int length) throws SAXException { String value = new String(ch,start,length); if (value.startsWith("\n")) { return; } System.out.println(value); } }
package com.darren.test.xml; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Transformer; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import org.xml.sax.helpers.AttributesImpl; public class SaxParse implements XmlParse { @Override public void createXml(String path) { try { SAXTransformerFactory sff = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); TransformerHandler th = sff.newTransformerHandler(); Result resultXml = new StreamResult(new FileOutputStream(path)); th.setResult(resultXml); Transformer transformer = th.getTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8"); // 编码格式是UTF-8 transformer.setOutputProperty(OutputKeys.INDENT,"yes"); // 换行 th.startDocument(); // 开始xml文档 AttributesImpl attr = new AttributesImpl(); th.startElement("","","employees",attr); // 定义employees节点 th.startElement("","employee",attr); // 定义employee节点 th.startElement("","name",attr); // 定义name节点 th.characters("Darren".tocharArray(),"Darren".length()); th.endElement("","name"); // 结束name节点 th.startElement("","sex",attr); // 定义sex节点 th.characters("man".tocharArray(),"man".length()); th.endElement("","sex"); // 结束gender节点 th.startElement("","age",attr); // 定义age节点 th.characters("25".tocharArray(),"25".length()); th.endElement("","age"); // 结束age节点 th.endElement("","employee"); // 结束employee节点 th.endElement("","employees"); // 结束employees节点 th.endDocument(); // 结束xml文档 } catch (Exception e) { e.printStackTrace(); } } @Override public void parseXml(String path) { SAXParserFactory saxfac = SAXParserFactory.newInstance(); try { SAXParser saxparser = saxfac.newSAXParser(); InputStream is = new FileInputStream(path); saxparser.parse(is,new MySAXHandler()); } catch (Exception e) { e.printStackTrace(); } } }
打印结果:
文档开始打印了 name:Darren sex:man age:25 文档打印结束了
3、DOM4J生成和解析XML文档
DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J
需要引入dom4j包
package com.darren.test.xml; import java.io.File; import java.io.FileWriter; import java.io.Writer; import java.util.Iterator; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4jParse implements XmlParse { @Override public void createXml(String path) { try { Document document = DocumentHelper.createDocument(); Element employees = document.addElement("employees"); Element employee = employees.addElement("employee"); Element name = employee.addElement("name"); name.setText("Darren"); Element sex = employee.addElement("sex"); sex.setText("man"); Element age = employee.addElement("age"); age.setText("25"); Writer fileWriter = new FileWriter(path); XMLWriter xmlWriter = new XMLWriter(fileWriter); xmlWriter.write(document); xmlWriter.close(); } catch (Exception e) { e.printStackTrace(); } } @Override @SuppressWarnings("unchecked") public void parseXml(String path) { try { File inputXml = new File(path); SAXReader saxReader = new SAXReader(); Document document = saxReader.read(inputXml); Element employees = document.getRootElement(); Iterator<Element> employeeElements = employees.elementIterator(); while (employeeElements.hasNext()) { Element employee = (Element) employeeElements.next(); Iterator<Element> nodeElements = employee.elementIterator(); while (nodeElements.hasNext()) { Element node = (Element) nodeElements.next(); System.out.println(node.getName() + ":" + node.getText()); } } } catch (Exception e) { e.printStackTrace(); } } }打印结果:
name:Darren sex:man age:25
4、JDOM生成和解析XML
为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档
需要引入jdom包
package com.darren.test.xml; import java.io.FileOutputStream; import java.util.List; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.XMLOutputter; public class JDomParse implements XmlParse { @Override public void createXml(String path) { try { Element root = new Element("employees"); Document document = new Document(root); Element employee = new Element("employee"); root.addContent(employee); Element name = new Element("name"); name.setText("Darren"); employee.addContent(name); Element sex = new Element("sex"); sex.setText("man"); employee.addContent(sex); Element age = new Element("age"); age.setText("25"); employee.addContent(age); XMLOutputter XMLOut = new XMLOutputter(); XMLOut.output(document,new FileOutputStream(path)); } catch (Exception e) { e.printStackTrace(); } } @Override @SuppressWarnings("unchecked") public void parseXml(String path) { try { SAXBuilder builder = new SAXBuilder(false); Document document = builder.build(path); Element root = document.getRootElement(); List<Element> employeeList = root.getChildren("employee"); for (Element employee : employeeList) { List<Element> employeeInfo = employee.getChildren(); for (Element info : employeeInfo) { System.out.println(info.getName() + ":" + info.getValue()); } } } catch (Exception e) { e.printStackTrace(); } } }打印结果:
name:Darren sex:man age:25测试类:
package com.darren.test.xml; public class XmlParseTest { public static void main(String[] args) { // DomParse domParse = new DomParse(); // domParse.createXml("F:\\employee.xml"); // domParse.parseXml("F:\\employee.xml"); // SaxParse saxParse = new SaxParse(); // saxParse.createXml("F:\\employee.xml"); // saxParse.parseXml("F:\\employee.xml"); // Dom4jParse dom4jParse = new Dom4jParse(); // dom4jParse.createXml("F:\\employee.xml"); // dom4jParse.parseXml("F:\\employee.xml"); JDomParse jdomParse = new JDomParse(); jdomParse.createXml("F:\\employee.xml"); jdomParse.parseXml("F:\\employee.xml"); } }