您的位置:首页 > 其它

xml常用四种解析方式优缺点的分析

2015-07-03 18:12 411 查看

xml常用四种解析方式优缺点的分析

博客分类:
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方式

Java代码


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解析方式

Java代码


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解析方式

Java代码


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解析方式

Java代码


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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: