浅析SAX,DOM,JAXP,JDOM与DOM4J之间的关系

java xml api

众所周知,SAXDOM是JAVA中两大核心XML解析API类库,而JAXP,JDOMDOM4J都是基于这两大核心API而衍生出来的。今日兴起看了看相关资料,写篇文章总结总结.

SAX与DOM

首先需要说明白的是SAX与DOM的关系。

SAXDOM都是底层API,在JDK中他们的包路径分别为:org.xml.sax与org.w3c.dom。自JDK1.5开始,JDK中自带的实现为Apache的xerces(位于com.sun.org.apache.xerces.internal.parsers下)。

SAXSimple API for XML的简称,它是在JAVA平台上第一个被广泛使用的XML API。也就说它是为JAVA而出现的。目前已经有多个语言版本,比如C++。
DOMDocuments Object Model的简称,与SAX不同的是,DOM是W3C的标准,它出现的目的是为了实现一套跨平台与语言的标准。

以上是它们之间的第一个不同。第二个,就是解析方式的不同。

SAX是基于事件解析,解析过程中根据目前的XML元素类型,调用用户自己实现的回调方法(或着叫事件方法)来处理,如:startDocument();startElement();
SAX2.0中有4个核心接口:

  • org.xml.sax.ContentHander
  • org.xml.sax.ErrorHandler
  • org.xml.sax.DTDHandler
  • org.xml.sax.EntityResolver

实现这几个Handler,然后调用解析器相应的set方法注册给解析器,就可以完成各种元素的解析与处理。 对应的注册进解析器的方法分别是:

  • parser.setContentHandler(ContentHander handler)
  • parser.setErrorHandler(ErrorHandler handler)
  • parser.setDTDHandler(DTDHandler handler)
    完整例子:
 DefaultHandler  handler=new XmlParserHandler();//DefaultHandler已经实现了全部org.xml.sax.ContentHandler,  
                                                   //org.xml.sax.ErrortHandler,org.xml.sax.DTDHandler和org.xml.sax.EntityHandler接口  
 XMLReader xr=XMLReaderFactory.createXMLReader();//获取解析器实例  
 xr.setContentHandler(handler);//设置处理类  
        xr.setErrorHandler(handler);  
        xr.setDTDHandler(handler);  
xr.setFeature("http://xml.org/sax/features/validation", true);//开启DTD验证  
xr.setFeature("http://apache.org/xml/features/validation/schema", true);//开启SCHMAE验证  
xr.parse(new InputSource("F:/Work/Workspace/XmlStudy/test.xml"));  

基于事件处理的好处是,不需要等到整个XML文件被加载完成后在开始处理,而是加载到哪处理到哪。这样便带来了效率上的优势。但是其也有明显的不足,第一个不足便是无法随机访问元素。如果你只想获取第二元素的信息,那么你必须等到第一个元素处理完成后,第二个元素开始的时候。如果这时,你又需要返回第一个元素,那么对不起,已经来不及了。SAX不会主动记忆或保存已处理过的元素(为了效率)。为了实现前面的需求,开发人员需要自己使用容器来保存处理过的元素,并且建立一个模型来表示XML的树形结构。这样一来也就带来了第二个缺点,使用的复杂性。

再来说说DOM。DOM采用了解析方式是一次性加载整个XML文档,在内存中形成一个树形的数据结构,这个数据结构我们称为文档对象模型。通过DOM解析器获取Documen文档t对象后,开发人员可以很方便的对其进行操作,如getDocumentElement();(获取更元素)getFirstChild();获取一个子元素appendChild();增加子元素removeChild();移除子元素。因此,使用DOM可以很方便对XML中的数据进行获取与修改,而不需要像SAX一样自己设计模型保存获取的数据。
完整例子:

  DOMParser dp=new DOMParser();  
  dp.parse(new InputSource("e:/test.xml"));  
  Document doc=dp.getDocument();  
  Element rootElemet=doc.getDocumentElement();  
  NodeList list=rootElemet.getChildNodes();  

跟重要的一点是,在DOM中所有Element都是Node,这意味着,我们不需要明确知道文档的结构就可以操作它。我们可以判断当前获取到的任意Node对象类型来做不同操作。主要Node类型有:
- Node.DOCUMENT_NODE
- Node.ELEMENT_NODE
- Node.TEXT_NODE
- Node.CDATA_SECTION_NODE
- Node.PROCESSING_INSTRUCTION_NODE
- Node.ENTITY_REFERENCE_NODE
- Node.DOCUMENT_TYPE_NODE

但是,由于DOM是一次性加载整个XML文件到内存, 如果XML文件非常庞大,构建文档树的内存与时间开销会很大,且很有可能导致内存溢出异常。

那么如何在SAX与DOM直接选择呢?这取决于下面几个因素:

  1. 应用程序的目的:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。
  2. 数据容量: 对于大型文件,SAX 是更好的选择。
  3. 数据将如何使用:如果只有数据中的少量部分会被使用,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。 另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX 也许不是恰当的选择。
  4. 对速度的需要: SAX 实现通常要比 DOM 实现更快。

SAXDOM 不是相互排斥的,记住这点很重要。您可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。事实上,用于创建 DOM 树的大多数解析器实际上都使用 SAX 来完成这个任务,比如DOM4JJDOM

JAXP,JDOM与DOM4J

JAXP

JAXP,全称Java API for XML Processing,打开其为JDK的目录:javax.xml.parsers, 你会发现它与SAX和DOM一样只是一套API。实际上,JAXP出现时SUN公司为了弥补JAVA在XML标准制定上的空白而制定的一套JAVA XML标准API。它并没有为JAVA解析XML提供任何新功能,但是它为在JAVA获取SAX与DOM解析器提供了更加直接的途径。它封装了SAX与DOM两种接口,并在SAX与DOM的基础之上,作了一套比较简单的api以供开发。
例如:JAXP获取SAX解析器:

  SAXParserFactory factory=SAXParserFactory.newInstance();  
  SAXParser parser=factory.newSAXParser();  
  parser.parse("F:/Work/Workspace/xiongqi/XmlStudy/test.xml", handler);  

获取DOM解析器:

  DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();  
  DocumentBuilder builder= factory.newDocumentBuilder();  
  Document document= builder.parse("F:/Work/Workspace/xiongqi/XmlStudy/test.xml");  

在 JAXP 的早期版本中,自带解析器的实现为 Apachede 的Crimson,在 JAXP 的新版本中 (包括在 JDK 中) ,Sun 已经重新包装了 Apache Xerces 做为解析器的实现。

JDOM

由于DOM是为了实现一套跨平台与语言的标准,因此使用它对于JAVA开发人员来说并不是特别的得心应手,这时JDOM就出现了。

JDOM 的目的是成为 Java 特定文档模型,它简化与 XML 的交互并且比使用 DOM 实现更快。而且它是第一个 Java 特定模型。与DOM相比较,首先,JDOM 仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API 大量使用了 Collections 类,相对于dom中的Node,简化了那些已经熟悉这些类的Java 开发者的使用。JDOM 自身不包含解析器,默认使用随jar包一起发行的pache Xerces。

例子:

SAXBuilder builder = new SAXBuilder(false);  
Document doc = builder.build(in);  

从上面代码中可以看出,JDOM使用SAX2 解析器来解析和验证输入 XML 文档,然后构建Doucment对象。

DOM4J

DOM4J 最初是 JDOM 的一个分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过 DOM4J API 和标准 DOM 接口具有并行访问功能。

为支持所有这些功能,DOM4J 使用接口抽象基本类方法。DOM4J 大量使用了 API 中的Collections 类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然 DOM4J 付出了更复杂的 API 的代价,但是它提供了比 JDOM 大得多的灵活性。在添加灵活性、XPath 集成和对大文档处理的目标时,DOM4J 的目标与 JDOM 是一样的:针对 Java开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案,实现在本质上处理所有Java/XML 问题的目标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为。

例子:

SAXReader reader = new SAXReader(false);  
Document  doc = reader.read(in);  

DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容