关于JAXP,DOM,SAX,JDOM,DOM4J的一些想法

关于 JAXP , DOM , SAX , JDOM , DOM4J 的一些想法

这些 API 是 XSLT 的关键部分,它们构建在 DOM 和 SAX 解析器基础上。

Sun 在 XML 领域总是后知后觉,等到 Sun 重视 XML 的时候, XML 的 API 早就满天 飞了,尤其是 IBM 具有非常大的领先优势。不过 Sun 是规范的制订者,于是参考 W 3C 的标准制订了 JAXP 规范。 JAXP 不像 Xerces 和 Crimon 那样,它只是一个 spec ,本身是不做任何事情的,它的作用就是提出一个统一的接口,让其它的 XML API 都来遵循 JAXP 编程,那么用 JAXP 写出来的程序,底层的 API 可以任意切换。

具体来说 JAXP 包括了几个工厂类,这就是 JDK1.4 里面的 javax.xml.parsers 包,用来寻找符合 DOM 标准的 XML API 实现类的位置;此外 JAXP 还包括一整套 interface ,这就是 JDK1.4 里面的 org.w 3c .dom 那几个包。工厂类负责加载 DOM 的实现类。

当你严格采用 JAXP 编程的时候,是遵循 W 3C 的 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 解析器

W 3C 的 DOM 标准 API 难用的让人想撞墙,于是有一帮人开发 Java 专用的 XML API 目的是为了便于使用,这就是 jdom 的由来,开发到一半的时候,另一部分人又分了出来,他们有自己的想法,于是他们就去开发 dom4j ,形成了今天这样两个 API ,至于他们之间的性能,功能之比较看看上面我推荐的文章就知道了, jdom 全面惨败。

jdom 相当于上面的 JAXP 接口 + Xerces DOM 实现部分,它本身没有解析器,它可以使用 Xerces 或者 Crimson 的解析器

jdom应用程序 -> jdom API -> Xerces/Crimson解析器


dom4j应用程序 -> dom4j API -> Xerces/Crimson解析器


dom4j应用程序 -> dom4j API -> Alfred2解析器

因此可以看出采用 dom4j/jdom 编写的应用程序,已经不具备可移植性了。

Sun 是 JAXP 标准的制订者,甚至很执著的在 JDK1.4 里面绑定 Crimson DOM 实现和解析器,然后可笑的是, Sun 自己的 JAXM RI 竟然不是用 JAXP 写出来的,而是 dom4j

我的举例:

1. 仅仅是 XSL 转换。 XML à HTML ,通过 XSL

Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

import java.io.FileOutputStream;

TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

这里的stream是一个DOM对象。


我感觉这个就是JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器,不知道对不对。


 


2.遍历XML,通过DOM。不仅仅是XSL转换。中间有对XML元素内容的操作。

Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

import java.io.FileOutputStream;

//Xerces 解析器来完成 DOM 遍历 XML.DOMParser 是 Xerces 包的一部分。

Import org.apache.xerces.parsers.DOMParser;

Import org.w 3c .dom.Document;

Import org.w 3c .dom.NodeList;

//DOM 遍历 XML

DOMParser parser = new DOMParser();

Parser.parse(XMLFileName);// 解析并在内存中创建 XML 树。

Document document = parser.getDocument();// 通过 Document 对象,可以使用内存中的树。

NodeList products = document.getElementByTagName(“product_id”);

Int num_products = products.getLength();

//XSL 转化器

TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

我感觉 XSL 转化和对 XML 对象的操作是两个过程。可以分别对待。最重要的是对对象的操作。这也就是为什么有 DOM,JDOM,DOM4J 。转化好像只需要 JAXP 就可以了,关心的是 StreamSource 和 StreamResult 。这两个是 DOM 对象。

 


3.JDOM使用,生成Document内容并保存到XML文件。


import org.jdom.Element;

import org.jdom.Document;// 和 Import org.w 3c .dom.Document 对比一下。一个是 JAXP 的一个是 JDOM 的 Document

import org.jdom.output.XMLOutputter;


 

Element root = Element(“orders”);

root.addContent(“ ”);

org.jdom.Document document = new Document(root);// 创建 JDOM 树。

FileOutputStream outStream = new FileOutputStream(XMLFileName);

XMLOutputter outToFile = new XMLOutputter();

outToFile.output(document,outStream);

outStream.flush();

outStream.close();

jdom应用程序 -> jdom API -> Xerces/Crimson解析器


VS


JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器


 

这里的没有 Transform 的过程,直接把 Document 的内容存到 XML 中。没有 XSL 转化,没有 XSL 文件。

JDOM 提供了几种输出方法。这里 XMLOutputter 是保存到文件,输出一个实际的 XML 流。还有 DOMOutputter, 在内存中创建一个传统的 DOM 树。还有 SAXOutputter ,创建一串 SAX 事件以便被其他对象读取。

 


 


4.JDOM使用,读取已有的XML然后生成Document,修改Document


import org.jdom.Element;

import org.jdom.Document;

import org.jdom.output.XMLOutputter;


   import org.jdom.input.SAXBuilder;


 


   SAXBuilder builder = new SAXBuilder();


   Document document = builder.build(XMLFileName);


 

Element order = Element(“orders”);

orders.addAttribute(“order_id”,session_id);

Element root = document.getRootElement();//root 是已经存在的根元素。

Root.addContent(order);// 在根元素里增加 orders 元素。

// 把 document 保存到文件中。

FileOutputStream outStream = new FileOutputStream(XMLFileName);

XMLOutputter outToFile = new XMLOutputter();

outToFile.output(document,outStream);

outStream.flush();

outStream.close();

即使创建一个 DOM 式的结构,这里仍使用 SAXBuilder 来做这这件事情。

DOMBuilder 和 SAXBuilder 中的 ”DOM” 和 ”SAX” 指的是用于建立文档的方法,而不是生成的内容。

 


 


5.XSL转换,能把DOM对象转化成输出,也可以向上面所举例的把XMLFileName的流转化成输出的流(文件或屏幕显示)。但是不能把JDOM对象转化,所以需要把JDOM转化成DOM对象,然后再输出。


import org.jdom.Element;

import org.jdom.Document;

import org.jdom.output.XMLOutputter;


   import org.jdom.input.SAXBuilder;   


   //XSL转化需要的包


 import org.jdom.output.DOMOutputter;//对比org.jdom.output.XMLOutputter;

Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.transform.DOMSource;// 对比 Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

  


  org.w3c.dom.Document DOMDoc;


  DOMOutputter DomOut = DOMOutputter();


  DOMDoc = DomOut.output(org.jdom.Document);//把jdom的document转化成DOM的document


  


  TransformFactory transFactory = TransformFactory.newInstance();


  Transformer transformer = transFactory.newTransformer(new DOMSource(DOMDoc));//感觉错了,应该是XSL文件。


  Transformer.transform(new DOMSource(DOMDoc),new StreamResult(out));


 


 //对比以前的转化,是从文件到文件,现在是DOM树到屏幕输出。

TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

刚学习XML,发现内容实在是太丰富了,仅仅是API就弄得有点乱。这篇文是我的第一个blog。呵呵!

Published At
Categories with Web编程
Tagged with
comments powered by Disqus