xml常用四种解析方式优缺点的分析×××××
最近用得到xml的解析方式,于是就翻了翻自己的笔记同时从网上查找了资料,自己在前人的基础上总结了下,贴出来大家分享下。
首先介绍一下xml语言:
可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
xml的语法:
XML 分为两部分:头信息,主体信息
头信息是用来描述 XML 的一些属性,例如:版本,编码等,还可以提供 XML 显示的样式,和 dtd 编写格式。
主体信息中包含的是 XML 的具体数据。
头信息的语法:
<?xml version =”1.0” encoding =”GBK” ?>
其中 version 是必须加的,而 encoding 可以不写,则默认编码是 ISO8859-1 ,不支持中文。
除了这个功能外,头信息还可以进行编写格式的规定,通过 dtd 或 xsd 文件。
头信息还支持样式表的导入,允许通过样式表控制 XML 的显示。
这样可以使用 XML+ CSS 完成页面的显示,通过这种形式完成 MVC 中的 View 层:
优点:代码的安全性很高,可以很容易的替换模板。
缺点:开发成本太高
主体信息 就是由三种节点组成的,节点之间存在父与子的关系,注意的点:
一个节点只能有一个父节点,如果没有父节点,该节点称为根节点。
一个节点可以有多个子节点。只有元素节点可以拥有子节点。
元素节点的标记必须成对出现,或直接结束。
特殊字符必须转义。依据字符所处的位置是否对 XML 格式造成影响来决定是否进行转义
根节点只能有一个
xml常用的四种解析方式:
1)DOM(Document Object Model)
文档对象模型分析方式。以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取和操作文档的任意部分。是W3C的官方标准。
优点:
1、允许应用程序对数据和结构做出更改。
2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。
缺点:
1、通常需要加载整个XML文档来构造层次结构,消耗资源大
2)SAX(Simple API for XML)
流模型中的推模型分析方式。通过事件驱动,每发现一个节点就引发一个事件,通过回调方法完成解析工作,解析XML文档的逻辑需要应用程序完成。
优点:
1、不需要等待所有数据都被处理,分析就能立即开始。
2、只在读取数据时检查数据,不需要保存在内存中。
3、可以在某个条件得到满足时停止解析,不必解析整个文档。
4、效率和性能较高,能解析大于系统内存的文档。
缺点:
1、需要应用程序自己负责TAG的处理逻辑(例如维护父/子关系等),使用麻烦。
2、单向导航,很难同时访问同一文档的不同部分数据,不支持XPath。
3)JDOM(Java-based Document Object Model)
Java特定的文档对象模型。自身不包含解析器,使用SAX。
优点:
1、使用具体类而不是接口,简化了DOM的API。
2、大量使用了Java集合类,方便了Java开发人员。
缺点:
1、没有较好的灵活性。
2、性能较差。
4)DOM4J(Document Object Model for Java)
简单易用,采用Java集合框架,并完全支持DOM、SAX和JAXP。
优点:
1、大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。
2、支持XPath。
3、有很好的性能。
缺点:
1、大量使用了接口,API较为复杂。
下面把四种解析方式的代码贴一下,首先是DOM方式
- public class DOMXml {
- public static void createXML(String outputPath) {
- // 建立Document对象
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- // 创建DocumentBuilder
- try {
- 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();
- // 包装要保存的doc
- DOMSource 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 block
- e.printStackTrace();
- } catch (ParserConfigurationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static void parseXML(String xmlPath) {
- /*优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
- * 缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
- * 使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
- * 10M文档导致内存溢出
- */
- // 建立Document对象
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- // 创建DocumentBuilder
- try {
- DocumentBuilder db = factory.newDocumentBuilder();
- // 创建Document,形成树型结构
- Document doc = db.parse(new File(xmlPath));
- // 先取得所有的data
- NodeList datas = doc.getElementsByTagName("data");
- // 循环取得每个data
- for (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 block
- e.printStackTrace();
- } catch (SAXException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.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;
- }
- @Override
- public void startDocument() throws SAXException {
- books = new ArrayList<Book>();
- }
- @Override
- public 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
- }
- @Override
- public 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,这不是我们想要的。
- */
- }
- @Override
- public 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 block
- e.printStackTrace();
- } catch (SAXException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.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 {
- // 建立多个Element
- Element 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 block
- e.printStackTrace();
- }
- }
- public static void parseXML(String xmlPath) {
- /*
- * 10M文档导致内存溢出
- */
- //完成解析功能。
- SAXBuilder builder = new SAXBuilder();
- try {
- Document doc = builder.build(new File(xmlPath));
- // 开始解析,取得根节点
- Element data = doc.getRootElement();
- // 取得所有的areaplus
- List<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");
- }
- }
- xml测试文件.rar (553 Bytes)
- 下载次数: 41
顶
踩
评论
在你的SAX解析方式里,有一个小bug.其他的没看。
50. @Override
51. public void characters(char[] ch, int start, int length)
52. throws SAXException {
53. if (preTag != null) {
54. String content = new String(ch, start, length);
55. if ("name".equals(preTag)) {
56. book.setName(book.getName() + content);
57. } else if ("price".equals(preTag)) {
58. book.setPrice(Float.parseFloat(content));
59. }
60. }
61. }
原因:当name是很长的文章的时候,就被切断了,结果出错了。
xml常用四种解析方式优缺点的分析×××××的更多相关文章
- xml的四种解析方式(转载)
众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...
- Java中XML的四种解析方式(一)
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析的方式都是一样的,只不过实现的语法不同而已. XML文档以层级标签的 ...
- XML解析——Java中XML的四种解析方式
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...
- XML解析——Java中XML的四种解析方式(转载 by 龍清扬)
XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便.XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已. XML的解析方式分为四 ...
- Java中XML的四种解析方式(二)
三.JDOM解析 特征: 1.仅使用具体类,而不使用接口. 2.API大量使用了Collections类. import org.jdom2.Attribute; import org.jdom2.D ...
- XML的四种解析方式
本文描述了构建良好的XML需要遵循的规则.作者详细介绍了构建XML需要考虑的元素,如何命名约定.正确的标记嵌套.属性规则.声明和实体,以及DTD和schema的验证,十分便于新手开始学习了解XML. ...
- XML 的4种解析方式
在上一篇博客中,我们介绍了什么是 XML ,http://www.cnblogs.com/ysocean/p/6901008.html,那么这一篇博客我们介绍如何来解析 XML . 部分文档引用:ht ...
- Android平台中实现对XML的三种解析方式
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- Web.xml中四种验证方式
源地址:https://blog.csdn.net/imimi_/article/details/78805642 <security-constraint> 的子元素 <http- ...
随机推荐
- Food on the Plane
Food on the Plane time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- Webkit之HTML解析
加载部分HTML文本(即主资源)后便可以开始解析HTML元素(对输入字节流进行逐字扫描,识别HTML元素),最后生成DOM树,本文只讲HTML解析. HTML解析部分时序图: 其中最为重要的过程是(1 ...
- C: define many functions using predefine..
/* Defines COUNTER. There must be exactly one such definition at file scope * within a program. */ # ...
- PullToRefreshScrollView的上拉加载、下拉刷新
eclipse中的项目: //注意:此刷新功能是使用的第三方的PullToRefreshScrollView,因此需要导入第三方library作为依赖 步骤:导入第三方library,依赖:点击你的应 ...
- Android中购物车的全选、反选、问题和计算价格
此Demo主要解决的是购物车中的全选,反选计算价格和选中的条目个数的问题,当选中几条时,点击反选,会把当先选中的变为不选中,把不选中的变为选中.点击全选会全部选中,再次点击时,变为全部不选中. //- ...
- Android自动化测试之环境搭建
Android自动化测试之环境搭建 一.Android-sdk介绍 SDK(Software development kit)软件开发工具包.被软件开发工程师用于为特定的软件包.软件框架.硬件平台. ...
- HDU 1054 Strategic Game 最小点覆盖
最小点覆盖概念:选取最小的点数覆盖二分图中的所有边. 最小点覆盖 = 最大匹配数. 证明:首先假设我们求的最大匹配数为m,那么最小点覆盖必然 >= m,因为仅仅是这m条边就至少需要m个点.然后 ...
- Struts的前世今身
1.Struts1的运行原理 a.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件( ...
- postfix疯狂外发垃圾邮件
分析 一.查找main.cf配置文件 localhost# find / -name main.cf /etc/postfix/main.cf 二.打开/etc/postfix/main.cf来看看. ...
- netty最快?
http://www.techempower.com/blog/2013/04/05/frameworks-round-2/