xml常用四种解析方式优缺点的分析
????? 最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。
首先介绍一下xml语言:
可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
public class DOMXml {public static void createXML(String outputPath) {// 建立Document对象DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建DocumentBuildertry {DocumentBuilder db = factory.newDocumentBuilder();// 创建Document,建立新的对象Document doc = db.newDocument();// 建立各个节点// 元素节点Element allplus = doc.createElement("allplus");Element areaplus = doc.createElement("areaplus");Element id = doc.createElement("id");Element title = doc.createElement("title");// 创建文本节点Text idText = doc.createTextNode("1");Text titleText = doc.createTextNode("123");// 配置父子节点的关系id.appendChild(idText);title.appendChild(titleText);areaplus.appendChild(id);areaplus.appendChild(title);allplus.appendChild(areaplus);// allplus是根节点,应该设置为doc的子节点doc.appendChild(allplus);// 执行保存操作TransformerFactory tf = TransformerFactory.newInstance();Transformer t = tf.newTransformer();// 包装要保存的docDOMSource source = new DOMSource(doc);// 设置输出流StreamResult sr = new StreamResult(new File(outputPath));// 设置输出的属性t.setOutputProperty("encoding", "UTF-8");// t.setOutputProperty("version", "1.0");// 输出t.transform(source, sr);} catch (DOMException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void parseXML(String xmlPath) {/*优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能; * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间; * 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。 * 10M文档导致内存溢出 */// 建立Document对象DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建DocumentBuildertry {DocumentBuilder db = factory.newDocumentBuilder();// 创建Document,形成树型结构Document doc = db.parse(new File(xmlPath));// 先取得所有的dataNodeList datas = doc.getElementsByTagName("data");// 循环取得每个datafor (int i = 0; i < datas.getLength(); i++) {Node data = datas.item(i);// 由于直接取得第一个和最后一个不符合要求,因此使用取得全部子节点的方式NodeList actorInfos = data.getChildNodes();for (int j = 0; j < actorInfos.getLength(); j++) {Node actorInfo = actorInfos.item(j);NodeList allChild = actorInfo.getChildNodes();for (int t = 0; t < allChild.getLength(); t++) {//判断节点Node child = allChild.item(t);if (child.getNodeType() == Node.ELEMENT_NODE) {if (child.getNodeName().equals("id")) {//判断是否有孩子节点,然后再取值if(child.hasChildNodes()) {System.out.println(child.getFirstChild().getNodeValue());}}if (child.getNodeName().equals("name")) {//判断是否有孩子节点,然后再取值if(child.hasChildNodes()) {System.out.println(child.getFirstChild().getNodeValue());}}}}}}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {parseXML("D:/actor_info.xml");createXML("d:/fxb.xml");}
?SAX解析方式
public class SAXXml extends DefaultHandler {private List<Book> books = null;private Book book = null;private String preTag = null;// 作用是记录解析时的上一个节点名称public List<Book> getBooks(InputStream xmlStream) throws Exception {SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();SAXXml handler = new SAXXml();parser.parse(xmlStream, handler);return handler.getBooks();}public List<Book> getBooks() {return books;}@Overridepublic void startDocument() throws SAXException {books = new ArrayList<Book>();}@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {if ("book".equals(qName)) {book = new Book();book.setId(Integer.parseInt(attributes.getValue(0)));}preTag = qName;// 将正在解析的节点名称赋给preTag}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if ("book".equals(qName)) {books.add(book);book = null;}preTag = null;/** * 当解析结束时置为空。这里很重要,例如,当图中画3的位置结束后,会调用这个方法 * ,如果这里不把preTag置为null,根据startElement(....)方法,preTag的值还是book,当文档顺序读到图 * 中标记4的位置时,会执行characters(char[] ch, int start, int * length)这个方法,而characters(....)方 * 法判断preTag!=null,会执行if判断的代码,这样就会把空值赋值给book,这不是我们想要的。 */}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if (preTag != null) {String content = new String(ch, start, length);if ("name".equals(preTag)) {book.setName(content);} else if ("price".equals(preTag)) {book.setPrice(Float.parseFloat(content));}}}public static void main(String args[]) {SAXXml handler = new SAXXml();// 定义SUN自带解析对象SAXParser parser;try {parser = SAXParserFactory.newInstance().newSAXParser();parser.parse(new File("D:/book.xml"), handler);} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}List<Book> books = handler.getBooks();for (Book book : books) {System.out.println(book.toString());}}
?JDOM解析方式
public class JDOMXml {public static void createXML(String outputPath) {// 先建立Document对象Document doc = new Document();// 建立元素节点Element allplus = new Element("allplus");try {// 建立多个ElementElement areaplus = new Element("areaplus");Element id = new Element("id");Element title = new Element("title");// 设置节点内容id.addContent("id");title.addContent("title");// 设置父子节点关系areaplus.addContent(id);areaplus.addContent(title);allplus.addContent(areaplus);// 设置根节点doc.setRootElement(allplus);// 使用IO流操作FileWriter writer = new FileWriter(new File(outputPath));// 定义输出对象XMLOutputter outputter = new XMLOutputter();// 设置编码outputter.setEncoding("UTF-8");// 输出outputter.output(doc, writer);writer.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void parseXML(String xmlPath) {/* * 10M文档导致内存溢出 *///完成解析功能。SAXBuilder builder = new SAXBuilder();try {Document doc = builder.build(new File(xmlPath));// 开始解析,取得根节点Element data = doc.getRootElement();// 取得所有的areaplusList<Element> actorInfos = data.getChildren("actor_info");if(actorInfos != null && actorInfos.size()>0) {for(Element actorInfo:actorInfos) {Element id = actorInfo.getChild("id");Element name = actorInfo.getChild("name");System.out.println(id.getTextTrim() + " --- " + name.getTextTrim());}}} catch (JDOMException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {parseXML("D:/actor_info.xml");createXML("d:/fdfdsf.xml");}
?DOM4J解析方式
package com.fxb.test;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.Writer;import java.util.Iterator;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.DocumentHelper;import org.dom4j.Element;import org.dom4j.io.SAXReader;import org.dom4j.io.XMLWriter;/** * * @author hongliang.dinghl Dom4j 生成XML文档与解析XML文档 */public class DOM4JXml {public void createXml(String fileName) {Document document = DocumentHelper.createDocument();Element employees = document.addElement("data");Element employee = employees.addElement("actor_info");Element id = employee.addElement("id");id.setText("1");Element name = employee.addElement("name");name.setText("你好");Element message = employee.addElement("message");message.setText("你好吗");Element pic = employee.addElement("pic");pic.setText("123");Element sex = employee.addElement("sex");pic.setText("男");Element birthday = employee.addElement("birthday");pic.setText("19881212");try {Writer fileWriter = new FileWriter(fileName);XMLWriter xmlWriter = new XMLWriter(fileWriter);xmlWriter.write(document);xmlWriter.close();} catch (IOException e) {System.out.println(e.getMessage());}}public void parserXml(String fileName) {File inputXml = new File(fileName);SAXReader saxReader = new SAXReader();try {Document document = saxReader.read(inputXml);Element data = document.getRootElement();for (Iterator i = data.elementIterator(); i.hasNext();) {Element actorInfo = (Element) i.next();//System.out.println(employee.getName() + "->" + employee.getText());for (Iterator j = actorInfo.elementIterator(); j.hasNext();) {Element child = (Element) j.next();System.out.println(child.getName() + ":" + child.getText());}System.out.println("=================");}} catch (DocumentException e) {System.out.println(e.getMessage());}}public static void main(String args[]) {DOM4JXml dom = new DOM4JXml();//dom.parserXml("d:/actor_info.xml");dom.createXml("d:/fxb.xml");}}?
?
?