一.XML
XML是一种可扩张标记语言,广泛用来标记数据、定义数据类型,是一种允许用户对自己的标 记语言进行定义的源语言.符合W3C标准.XML是无作为的,不会做任何事情,只用于数据的描述,储存和传输.同时XML也是无所不在的,在Web中的作用不亚于HTML,XML 是各种应用程序之间进行数据传输的最常用的工具.
二.推模型和拉模型.
推模型是当消息来之时,把所有相关信息都通过参数的形式"推给"观察者.事件驱动编程(Event-driven programming),基于回调(callback)机制,也就是推模型,即使不需要也把数据推给你.拉模型是当通知消息来之时,通知的函数不带任何相关的信息,而是要观察者主动去“拉”信息,通过轮询(loop check)实现就是拉模型,给你一个引用,数据在拉之前全部准备好了,需要是拉需要.
三.XML处理方式
主要有两种:基于树和基于事件驱动的.很多XML解析器,包括MSXML的最新版本对两种模型都支持.基于树的解析器通常称为DOM(document object model 文档对象模型)解析器,而基于事件驱动的解析器通常被称为SAX(simple API for XML 简单应用编程接口)解析器.二者都是以它们支持的规则命名的.
DOM是W3C推荐的XML文档应用接口(API)的标准.所有的程序都可以这个API来操作XML,读取信息,添加节点以及编辑当前的内容.而SAX并不是W3C的推荐标准,但也得到了大大小小软件公司的支持.基于SAX的解析器顺序地读取XML文本,当它遇到文档中的重要部分时就触发事件,比如在元素的起始或结束的位置.
两种处理模型都有优点.DOM的解析提供了对XML文档的完整的读写访问,并且可以通过遍历文档树对文档内的节点进行访问.还可以对照DTD或XML模式来判断一个文档是否有效,然而,DOM的解析必须将XML文档整个读入内存中,所以当遇到较大的XML文档时,DOM解析就会变得较慢而且比较消耗内存.很难准确判断何种XML文档才是过大的,因为处理时间会根据能力,内存,可用时间以及是否在单用户或多用户环境下工作而变化.一般而言,大多数系统可以处理大至几十兆的文件,但是对于更大的文件就需要十分小心了.另一方面,SAX的模型是串行操作的.一个节点被处理后就被丢弃了,并且不会再被处理.整个文档并不一次性的读入内存中,这样就避免了由较大的XML文档而引起的处理问题.这种处理方法将由用户负责保存XML文档中的可供后续使用的信息.
举个例子,对于一个通信系统的中间路由程序来说,SAX是理想的.一个读入的XML文档通常只有一个很小的路由首部信息,但却有需要发送到终点的较大文档.使用SAX模型时,路由设备可以仅读取路由信息而忽略掉整个文档,因为文档与传递并无关系.然而,DOM的解析器却需要在读取整个文档后才可以将之传至终点.
四.DOM解析.
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找 特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的.DOM解析器把XML文档转化为一个包含其内容的树,并可以对树进行遍历.DOM是拉模型,在遍历文档时,会把感兴趣的部分从读取器中拉出,不需要引发事件,允许我们选择性地处理节点.这大大提高了灵活性,以及整体效率.
public static void domParse() throws Exception {
File file =
new File("F:/test/web项目/workspace/xml/src/users.xml");
//1、创建DocumentBuilder工厂
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
//2、创建DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();
//3、将xml文件解析为Document对象,代表DOM树
Document document = db.parse(file);
//将文档标准化,去除无用的空格和空行,即删除无用的text node
document.normalize();
NodeList nodeList = document.getElementsByTagName("user");
for(int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
System.out.println("======user start=======");
String uuid = element.getElementsByTagName("uuid").item(0).getTextContent();
System.out.println(uuid);
String name = element.getElementsByTagName("name").item(0).getTextContent();
System.out.println(name);
System.out.println("======user end=======");
}
DOM有5个基本对象:document,node,nodelist,element,attr.
1.document对象
代表了整个XML的文档,所有其它的Node,都以一定的顺序包含在Document对象之内,排列成一个树形的结构,程序员可以通过遍历这颗树来得到XML文档的所有的内容,这也是对XML文档操作的起点.我们总是先通过解析XML源文件而得到一个Document对象,然后再来执行后续的操作.此外,Document还包含了创建其它节点的方法,比如createAttribute()用来创建一个Attr对象.
2.node对象
DOM结构中最为基本的对象,代表了文档树中的一个抽象的节点.在实际使用的时候,很少会真正的用到Node这个对象,而是用到诸如Element、Attr、Text等Node对象的子对象来操作文档.Node对象为这些对象提供了一个抽象的、公共的根.虽然在Node对象中定义了对其子节点进行存取的方法,但是有一些Node子对象,比如Text对象,它并不存在子节点,这一点是要注意的.
3.nodelist对象
顾名思义,就是代表了一个包含了一个或者多个Node的列表.可以简单的把它看成一个Node的数组,我们可以通过方法来获得列表中的元素:getLength();返回列表的长度,item(int);返回指点位置的node对象
4.element对象
代表的是XML文档中的标签元素,继承于Node,亦是Node的最主要的子对象.在标签中可以包含有属性,因而Element对象中有存取其属性的方法.而任何Node中定义的方法,也可以用在Element对象上面.
5.attr对象
代表了某个标签中的属性.Attr继承于Node,但是因为Attr实际上是包含在Element中的,它并不能被看作是Element的子对象,因而在DOM中Attr并不是DOM树的一部分,所以Node中的getParentNode(),getPreviousSibling()和getNextSibling()返回的都将是null.也就是说,Attr其实是被看作包含它的Element对象的一部分,它并不作为DOM树中单独的一个节点出现.这一点在使用的时候要同其它的Node子对象相区别.
五.SAX解析
SAX是Simple API for XML的缩写,它并不是由W3C官方所提出的标准,可以说是“民间”的事实标准.实际上,它是一种社区性质的讨论产物.虽然如此,在XML中对SAX的应用丝毫不比DOM少,几乎所有的XML解析器都会支持它.
与DOM比较而言,SAX是一种轻量型的方法.我们知道,在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象.当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当费时费力.特别是其对于内存的需求,也将是成倍的增长,以至于在某些应用中使用DOM是一件很不划算的事(比如在applet中).这时候,一个较好的替代解决方法就是SAX.
SAX在概念上与DOM完全不同.首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程.所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法.(如果你对Java新的代理事件模型比较清楚的话,就会很容易理解这种机制了)
回调:由我们在组件中定义,而不由我们调用,由容器或框架调用
SAX是推模型,它是一种靠事件驱动的模型.当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序.这样的做法很麻烦,且不灵活.
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SaxTest {
public static void main(String[] args) throws Exception {
saxParse();
}
private static void saxParse() throws Exception {
File file = new File("F:/test/web项目/workspace/xml/src/users.xml");
//1、创建SAXParserFactory 工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
//2、创建SAXParser
SAXParser sp = spf.newSAXParser();
//3、解析XML文档,并回调处理器的相应事件
sp.parse(file, new UserSaxHandler());
}
}
六.StAX解析
针对于XML的流式API(StAX),是在2004年3月的JSR 173规范中引入,这是一种针对XML的流式拉分析API.StAX是JDK 6.0提供的一种新特征.
一个推模型分析器不断地生成事件,直到XML文档被完全分析结束.但是,拉分析由应用程序进行调整;因此,分析事件是由应用程序生成的.这意味着,使用StaX,你可以推迟分析-在分析时跳过元素并且分析多个文档.在使用DOM API的时候,你必须把整个的XML文档分析成一棵DOM结构,这样也就降低了分析效率.而借助于StAX,在分析XML文档时生成分析事件.
七.JDOM解析
JDOM的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快.由于是第一个Java特定模型,JDOM一直得到大力推广和 促进.正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”.从2000年初就已经开始了JDOM开发.
JDOM与DOM主要有两方面不同.首先,JDOM仅使用具体类而不使用接口.这在某些方面简化了API,但是也限制了灵活性.第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用.
JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%).JDOM对于大多数 Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得多.JDOM还包括对程序行为的相当广泛检查以防止用户做任何 在XML中无意义的事.然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误).这也许是比学习DOM或JDOM接口 都更有意义的工作.
JDOM自身不包含解析器.它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入).它包含一些转换器以将 JDOM表示输出成SAX2事件流、DOM模型或XML文本文档.JDOM是在Apache许可证变体下发布的开放源码.
八.DOM4J解析
虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支.它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、 XML Schema支持以及用于大文档或流化文档的基于事件的处理.它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能.从2000下半年开始,它就一直处于开发之中.
为支持所有这些功能,DOM4J使用接口和抽象基本类方法.DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替 代方法以允许更好的性能或更直接的编码方法.直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性.
在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作.它还致力于成为比 JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标.在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为.
DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件.如今你可以看到越来越多的Java软件都在使用DOM4J来读写 XML,特别值得一提的是连Sun的JAXM也在用DOM4J.
九.比较
1.DOM:拉模型,把整个文档加载到内存中
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)
2.SAX:推模型,事件驱动编程,基于回调SAX ,事件驱动.当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据.
优点:不用事先调入整个文档,占用资源少;
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
使用场合:数据量较大的XML文档,占用内存高,机器内存少,无法一次加载XML到内存;只需XML文档的少量内容,很少回头访问;
3.JDOM :为减少DOM、SAX的编码量,出现了JDOM;
优点:20-80原则,极大减少了代码量,提供常用API减少重复劳动
使用场合:要实现的功能简单,如解析、创建等Java程序,但在底层,JDOM还是使用SAX(最常用)、DOM
十.性能比较
1.DOM4J性能最好,连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件.如果不考虑可移植性,那就采用DOM4J.
2.JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出.在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明 他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处.另外,DOM仍是一个非常好的选择.DOM实现广泛应用于多种编程语 言.它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在 javascript中使用DOM).
3.SAX表现较好,这要依赖于它特定的解析方式-事件驱动.一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)
将XML保存到文件中
private Document newDocument() throws ParserConfigurationException {
//1、创建DocumentBuilder工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//2、创建DocumentBuilder
DocumentBuilder db;
db = dbf.newDocumentBuilder();
Document document = db.newDocument();
document.setXmlVersion("1.0");
Element element = document.createElement("users");
document.appendChild(element);
return document;
}
private void createXmlFile(Document document) throws TransformerConfigurationException, TransformerException {
//1、创建转换工程
TransformerFactory tf = TransformerFactory.newInstance();
//2、创建DOM源
DOMSource ds = new DOMSource(document);
//3、新建一个文件用于存储XML
File file = new File(fileName);
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//将文件包装为结果
StreamResult sr = new StreamResult(file);
//转换
tf.newTransformer().transform(ds,sr);
}
public void saveToXml() {
Document document;
try {
document = newDocument();
Element usersElement =
(Element) document.getElementsByTagName("users").item(0);
for(UserModel um : userList) {
Element userElement = document.createElement("user");
Element uuidElement = document.createElement("uuid");
Element nameElement = document.createElement("name");
usersElement.appendChild(userElement);
userElement.appendChild(uuidElement);
userElement.appendChild(nameElement);
uuidElement.setTextContent(String.valueOf(um.getUuid()));
nameElement.setTextContent(um.getName());
}
createXmlFile(document);
} catch (Exception e) {
e.printStackTrace();
}
}
分享到:
相关推荐
KXML2是一个用于Java平台上的轻量级XML解析库,主要应用于移动设备等资源受限的环境中。它采用Pull解析模式,即开发者通过一系列方法调用来“拉取”XML文档中的数据,而不是由解析器主动推送数据给应用程序。这种...
本文将围绕“浅谈jxl解析excel ——复制、修改excel表”这一主题,深入探讨JXL库的使用方法和关键知识点。 首先,JXL库提供了丰富的API,使得开发人员可以方便地操作Excel文件的各个部分,如工作表、单元格、样式等...
在没有DTD或Schema的情况下,XML解析器可以确保文档至少是格式良好的XML文档,即遵守XML的基本语法规则。 此外,XML文档中的根元素通常定义了文档的类型,它包含了文档的结构描述,如示例中的根元素,它表明了整个...
如果一个XML文档包含多个没有命名空间的同名元素,就会造成解析错误。 设置elementFormDefault为unqualified的schema示例如下: ```xml <?xml version="1.0" encoding="UTF-8"?> ***" xmlns:sean="***" ...
在“浅谈第一次使用”的描述中,可能涵盖了博主初次尝试使用Digester时的经验和遇到的问题,以及逐步理解和掌握该工具的过程。由于描述信息为空,我们无法获取具体的细节,但可以假设内容可能包括了基本概念介绍、...
### 浅谈SOAP知识点解析 #### 一、为什么需要SOAP? 随着信息技术的飞速发展,企业面临着日益复杂的信息化挑战。为了适应这种变化,现代企业信息系统往往由多个平台和技术构成,形成了复杂的多系统环境。这样的...
"浅谈与AJAX相关的几种技术" 本文将对与AJAX相关的几种技术进行简单介绍,包括XHTML、CSS、XML、XSLT和DOM等。 首先,AJAX技术丰富的功能、交互性以及快速的响应能力受到人们广泛青睐,但实际上AJAX是多种老技术的...
### 浅谈Soap Web Service架构及其应用 #### 一、背景与发展趋势 随着互联网时代的到来,信息技术的发展使得传统的局域网或单机式信息服务结构已无法满足现代社会的需求。分布式应用技术逐渐成为主流,以适应日益...
【XPath】XPath是一种在XML文档中查找信息的语言,尽管这里主要讨论的是HTML解析,但XPath的概念同样适用。XPath用于选取XML或HTML文档中的节点,如元素、属性和文本。它通过路径表达式来选取节点,这些表达式可以是...
"浅谈JAVA中JSON的应用——以天气预报数据接口为例" JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它采用完全独立于编程语言的文本格式来存储和表示数据,不但易于人阅读和编写,同时也易于机器...
1. **禁用外部实体加载:** 在解析XML文档时,确保XML解析器不会加载外部实体。 2. **限制XML解析器的功能:** 配置解析器以降低其功能,减少潜在风险。 #### 失效的访问控制 **原理:** 访问控制失效意味着应用...
对于EL表达式的解析而言,需要web.xml中的web-app元素的schemaLocation指向的XML Schema支持EL表达式。如果使用的XML Schema版本过旧,可能不支持EL表达式,从而导致解析失败。在文章中提到了web-app_2_2.xsd至web-...
### 浅谈Android的Selector背景选择器 #### 一、引言 在Android开发中,为了提高用户体验,经常需要对控件的外观进行定制化处理,特别是在不同的交互状态下展示不同的视觉效果。`Selector`作为Android中一个非常...
最近有同学询问如何利用Python处理xml文件,特此整理一个比较简洁的操作手册,供大家参阅。 首先准备一个xml文件,xml中的内容如下所示。存储为:student.xml 如果要获取这个xml里面的数据,我们需要利用Python里面...
3. **浅谈C# WinForm中实现基于角色的权限菜单.txt**:这可能是详细阐述如何在WinForm中实现RBAC的文本文件,包括代码示例和步骤解析。 4. **UpgradeLog.XML**:升级日志文件,记录了软件升级过程中的信息。 5. **DB...