SAX: Simple API for XML
DOM: Document Object Model
JAXP: Java API for XML Processing
StAX: The Streaming API for XML
1、SAX, DOM是两种对xml文档进行分析的方法(没有具体的实现,只有接口)所以他们不是解释器,仅仅靠他们是完成不了对xml文档的处理的。
sax的包是org.xml.sax
dom的包是org.w3c.dom
包的名称很重要,它有助于你理解他们之间的关系。 可见,DOM是W3C的官方规范。
容易混淆的是,人们常说用JDK中自带的SAX/DOM方式来解析XML (相对于与JDom和Dom4J的解析方式),确实,JDK不需要引入任何额外的依赖就可以解析XML,貌似是JDK自己实现了SAX/DOM,这是为什么呢?其实就是JAXP在作怪,它偷偷的把别人的一些实现包进了JDK中,继续往下看。
2. JAXP
Sun在XML领域总是后知后觉,等到Sun重视XML的时候,XML的API早就满天飞了,尤其是IBM具有非常大的领先优势。不过Sun是规范的制订者,于是参考W3C的标准制订了JAXP规范。
所以JAXP也不是具体的实现,只是个API,所以仅有JAXP也是无法工作的。它封装了SAX/DOM两种接口(后来又添加了STAX接口)。并在SAX/DOM的基础上作了一套比较简单的API以供开发人员使用。
JAXP的包是javax.xml.parsers
JAXP它只是一个规范,完成了对SAX、DOM的包装,生成了DocumentBuilderFactory、 DocumentBuilder和SAXParserFactory、SAXParser。也就是设计模式中的工厂模式,他的好处就是具体的对象(解释器)建立由子类完成。JAXP的作用就是提出一个统一的接口,让其它的XML API都来遵循JAXP编程。当你严格采用JAXP编程的时候,是遵循W3C的DOM标准的,那么在JAXP底层你实际上可以任意切换不同的DOM实现(也就是解释器),例如Xerces,或者Crimon,再或者其它,切换方法就是配置jaxp.properties。因此JAXP就是一些标准接口而已。
JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器
JAXP应用程序 -> JAXP接口 -> Crimson DOM实现 -> Crimson DOM/SAX 解析器
JAXP应用程序 -> JAXP接口 -> Crimson DOM实现 -> Xerces DOM/SAX 解析器
比如,先以DOM为例,当实例化一个DocumentBuilderFactory的时候是用
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
这个newInstance()就是先去jaxp.properties中去找你配置好的实现类,如果找不到,就会回滚到默认的
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl,
显然这个就是人家Apache对JAXP的实现类,只是被放到了JDK默认的包里。
同样的道理,JDK的SAX是用
SAXParserFactory sf = SAXParserFactory.newInstance();
它默认会被会滚到
com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl,
同样是Apache的Xerces的实现。
但是,要注意的是,JDK自己实现了StAX的实习方式,StAX和SAX的区别:
SAX也是基于事件处理xml文档,但却是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件。SAX中解析器是工作主体,而事件处理器是由解析器驱动的,如果解析文档过程中产生问题,则剩余的所有文档就无法处理。
StAX使用拉模式,解析器首先将XML文档所有的事件全部取出,然后通过处理程序处理这些事件。StAX中处理器是工作主体,如果解析文档过程中产生问题,只会影响到出问题的部分,其余部分处理不受影响。
创建XMLInputFactory
XMLInputFactory factory = XMLInputFactory.newInstance();
它的实现类是JDK自己的com.sun.xml.internal.stream.XMLInputFactoryImpl
3. JDom & Dom4j
W3C的DOM标准API难用的让人想撞墙,于是有一帮人开发Java专用的XML API目的是为了便于使用,这就是JDom的由来,开发到一半的时候,另一部分人又分了出来,他们有自己的想法,于是他们就去开发Dom4j,形成了今天这样两个API,至于他们之间的性能,JDom全面惨败,Dom4j大获全胜。
JDOM、DOM4J相当于上面的JAXP接口+DOM实现部分,它本身没有解析器,它可以使用Xerces或者Crimson的解析器。
jdom应用程序 -> jdom API -> Xerces/Crimson解析器
dom4j应用程序 -> dom4j API -> Xerces/Crimson解析器
dom4j应用程序 -> dom4j API -> Alfred2解析器
4. xerces解释器
在Apache xerces中对jaxp中定义的SAXParser、SAXParserFactory、DocumentBuilder、DocumentBuilderFactory进行了继承,对应SAXParserImpl、SAXParserFactoryImpl、DocumentBuilderImpl、DocumentBuilderFactoryImpl
这就是为什么你的classpath中只要有xerces.jar(其中包含了sax dom jaxp )和 xercesImpl.jar就可以的原因了.
5. Apache Crimson
前身是Sun Project X Parser, 至今Apache Crimson的很多代码都是从X Parser中直接移植过来的。早期的JAXP是和X Parser捆绑在一起的。后来的 JAXP和Apache Crimson捆绑在一起,比如JAXP 1.1。最新的JAXP 1.2 EA(Early Access)改弦更张,采用性能更好的Apache Xalan和Apache Xerces分别作为XSLT处理器和XML解析器,不能直接支持Apache Crimson了,因为其Apache Crimson效率低下
6. Xalan
是一个XSLT处理器。JAXP的XSLT引擎(Transformer类)来输出XML文档,这种方法也许是标准的方法 了,使用起来十分灵活,特别是可以自如控制输出格式,是将来创建/更新XML的主流方法
7. DOM是W3C的官方标准, 而SAX非W3C官方标准,是民间事实标准,一种社区性质的讨论产物。
(1). DOM将整个XML文档载入到内存中处理,DOM以一个分层的对象模型来映射xml文档:在内存中创建DOM树,生成DOM树上的每个Node对象。
(2). SAX则相反,它将文档中的元素转化为对象来处理,可以检测一个即将到来的 XML流,由此并不需要所有的XML代码同时载入到内存中。
8. XSL: XML Stylesheet Language
9. XSLT: XML Stylesheet Language Transformations