posts - 431,  comments - 344,  trackbacks - 0

一、 JDOM  简介
JDOM
是一个开源项目,它基于树型结构,利用纯 Java 的技术对 XML 文档实现解析、生成、序列化以及多种操作。
JDOM 
直接为 Java 编程服务。它利用更为强有力的 Java 语言的诸多特性(方法重载、集合概念以及映射),把 SAX DOM 的功能有效地结合起来。
在使用设计上尽可能地隐藏原来使用 XML 过程中的复杂性。利用 JDOM 处理 XML 文档将是一件轻松、简单的事。
JDOM 
2000 年的春天被 Brett McLaughlin Jason Hunter 开发出来,以弥补 DOM SAX 在实际应用当中的不足之处。
这些不足之处主要在于 SAX 没有文档修改、随机访问以及输出的功能,而对于 DOM 来说, Java 程序员在使用时来用起来总觉得不太方便。
DOM
的缺点主要是来自于由于 Dom 是一个接口定义语言( IDL , 它的任务是在不同语言实现中的一个最低的通用标准,并不是为 Java 特别设计的。 JDOM 的最新版本为 JDOM Beta 9 。最近 JDOM 被收录到 JSR-102 内,这标志着 JDOM 成为了 Java 平台组成的一部分。


二、 JDOM  包概览
JDOM
是由以下几个包组成的
org.JDOM
org.JDOM.input
org.JDOM.output
org.JDOM.adapters
org.JDOM.transform

三、 JDOM  类说明

org.JDOM
这个包里的类是你解析 xml 文件后所要用到的所有数据类型。
Attribute
CDATA
Coment
DocType
Document
Element
EntityRef
Namespace
ProscessingInstruction
Text

org.JDOM.transform
在涉及 xslt 格式转换时应使用下面的 2 个类
JDOMSource
JDOMResult

org.JDOM.input
输入类,一般用于文档的创建工作
SAXBuilder
DOMBuilder
ResultSetBuilder

org.JDOM.output
输出类,用于文档转换输出
XMLOutputter
SAXOutputter
DomOutputter
JTreeOutputter

使用前注意事项:
1.JDOM
对于 JAXP  以及  TRax  的支持
JDOM 
支持 JAXP1.1 :你可以在程序中使用任何的 parser 工具类 , 默认情况下是 JAXP parser
制定特别的 parser 可用如下形式
SAXBuilder parser 
= new SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");
Document doc = parser.build("http://www.cafeconleche.org/");
// work with the document...
JDOM
也支持 TRaX XSLT 可通过 JDOMSource 以及 JDOMResult 类来转换(参见以后章节)
2.
注意在 JDOM 里文档( Document )类由 org.JDOM.Document  来表示。这要与 org.w3c.dom 中的 Document 区别开,这 2 种格式如何转换在后面会说明。
以下如无特指均指 JDOM 里的 Document


四、 JDOM 主要使用方法
1.Ducument

(1)Document
的操作方法:
Element root = new Element("GREETING");
Document doc = new Document(root);
root.setText("Hello JDOM!");
或者简单的使用 Document doc = new Document(new Element("GREETING").setText("Hello JDOM!t"));

这点和 DOM 不同。 Dom 则需要更为复杂的代码,如下:
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder =factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element root =doc.createElement("root");
Text text = doc.createText("This is the root");
root.appendChild(text);
doc.appendChild(root);


注意事项: JDOM 不允许同一个节点同时被 2 个或多个文档相关联,要在第 2 个文档中使用原来老文档中的节点的话。首先需要使用 detach() 把这个节点分开来。

(2)
从文件、流、系统 ID URL 得到 Document 对象:
DOMBuilder builder = new DOMBuilder();
Document doc = builder.build(new File("jdom_test.xml"));

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(url);
在新版本中 DOMBuilder  已经 Deprecated  DOMBuilder.builder(url) ,用 SAX 效率会比较快。

这里举一个小例子,为了简单起见,使用 String 对象直接作为 xml 数据源:

public jdomTest() {
  String textXml = null;
  textXml = "<note>";
  textXml = textXml +
    "<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";
  textXml = textXml + "</note>";
  SAXBuilder builder = new SAXBuilder();
  Document doc = null;
  Reader in= new StringReader(textXml);
  try {
    doc = builder.build(in);
    Element root = doc.getRootElement();
    List ls = root.getChildren();//
注意此处取出的是 root 节点下面的一层的 Element 集合
    for (Iterator iter = ls.iterator(); iter.hasNext(); ) {
    Element el = (Element) iter.next();
    if(el.getName().equals("to")){
      System.out.println(el.getText());
    }
    }
  }
  catch (IOException ex) {
    ex.printStackTrace();
  }
  catch (JDOMException ex) {
    ex.printStackTrace();
  }
}

很简单把。


(3)DOM
document JDOM Document 之间的相互转换使用方法,简单!
DOMBuilder builder = new DOMBuilder();
org.jdom.Document jdomDocument = builder.build(domDocument);
// work with the JDOM document…

DOMOutputter converter = new DOMOutputter();
org.w3c.dom.Document domDocument = converter.output(jdomDocument);
// work with the DOM document…

2.XML
文档输出
XMLOutPutter
类:
JDOM
的输出非常灵活 , 支持很多种 io 格式以及风格的输出
Document doc = new Document(...);
XMLOutputter outp = new XMLOutputter();
// Raw output
outp.output(doc, fileOutputStream);
// Compressed output
outp.setTextTrim(true);
outp.output(doc, socket.getOutputStream());
// Pretty output
outp.setIndent(" ");
outp.setNewlines(true);
outp.output(doc, System.out);
......
详细请参阅最新的 JDOM API 手册


3.Element 
类:
(1)
浏览 Element
//
获得根元素 element
Element root = doc.getRootElement();
// 
获得所有子元素的一个 list
List allChildren = root.getChildren();
// 
获得指定名称子元素的 list
List namedChildren = root.getChildren("name");
//
获得指定名称的第一个子元素
Element child = root.getChild("name");
(这里的 List Java.util.List

JDOM
给了我们很多很灵活的使用方法来管理子元素
List allChildren = root.getChildren();
// 
删除第四个子元素
allChildren.remove(3);
// 
删除叫 “jack” 的子元素
allChildren.removeAll(root.getChildren("jack"));

root.removeChildren("jack"); // 
便捷写法
// 
加入
allChildren.add(new Element("jane"));

root.addContent(new Element("jane")); // 
便捷写法
allChildren.add(0, new Element("first"));


(2)
移动 Elements:
JDOM 里很简单
Element movable = new Element("movable");
parent1.addContent(movable); // place
parent1.removeContent(movable); // remove
parent2.addContent(movable); // add

Dom
Element movable = doc1.createElement("movable");
parent1.appendChild(movable); // place
parent1.removeChild(movable); // remove
parent2.appendChild(movable); // 
出错 !

补充:
纠错性
JDOM
Element 构造函数(以及它的其他函数)会检查 element 是否合法。
而它的 add/remove 方法会检查树结构,检查内容如下:
1.
在任何树中是否有回环节点
2.
是否只有一个根节点
3.
是否有一致的命名空间( Namespaces



(3)Element
text 内容读取
<description>
A cool demo
</description>

// The text is directly available
// Returns "\n A cool demo\n"
String desc = element.getText();

// There's a convenient shortcut
// Returns "A cool demo"
String desc = element.getTextTrim();

(4)Elment
内容修改
element.setText("A new description");
3.
可正确解释特殊字符
element.setText("<xml> content");
4.CDATA
的数据写入、读出
element.addContent(new CDATA("<xml> content"));
String noDifference = element.getText();

混合内容
element
可能包含很多种内容,比如说

<table>
<!-- Some comment -->
Some text
<tr>Some child element</tr>
</table>

table 的子元素 tr
String text = table.getTextTrim();
Element tr = table.getChild("tr");

也可使用另外一个比较简单的方法
List mixedCo = table.getContent();
Iterator itr = mixedCo.iterator();
while (itr.hasNext()) {
Object o = i.next();
if (o instanceof Comment) {
...
}
// 
这里可以写成 Comment, Element, Text, CDATA,ProcessingInstruction,  或者是 EntityRef 的类型
}
// 
现在移除 Comment, 注意这里游标应为 1 。这是由于回车键也被解析成 Text 类的缘故 , 所以 Comment 项应为 1
mixedCo.remove(1);



4.Attribute

<table width="100%" border="0"> </table>
//
获得 attribute
String width = table.getAttributeValue("width");
int border = table.getAttribute("width").getIntValue();
//
设置 attribute
table.setAttribute("vspace", "0");
// 
删除一个或全部 attribute
table.removeAttribute("vspace");
table.getAttributes().clear();



5.
处理指令 (Processing Instructions) 操作
一个 Pls 的例子
<?br?>
<?cocoon-process type="xslt"?>
      |     |
      |     |
    
目标     数据

处理目标名称 (Target)
String target = pi.getTarget();
获得所有数据( data ),在目标( target )以后的所有数据都会被返回。
String data = pi.getData();
获得指定属性的数据
String type = pi.getValue("type");
获得所有属性的名称
List ls = pi.getNames();

6.
命名空间操作
<xhtml:html 
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:title>Home Page</xhtml:title>
</xhtml:html>

Namespace xhtml = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml");
List kids = html.getChildren("title", xhtml);
Element kid = html.getChild("title", xhtml);
kid.addContent(new Element("table", xhtml));

7.XSLT
格式转换
使用以下函数可对 XSLT 转换
最后如果你需要使用 w3c Document 则需要转换一下。
public static Document transform(String stylesheet
Document in)
                          throws JDOMException {
  try {
    Transformer transformer = TransformerFactory.newInstance()
                  .newTransformer(new StreamSource(stylesheet));
    JDOMResult out = new JDOMResult();
    transformer.transform(new JDOMSource(in), out);
    return out.getDeocument();
  }
  catch (TransformerException e) {
    throw new JDOMException("XSLT Trandformation failed", e);
  }
  }

参考书目:

1.JDOM
官方网站:  http://www.jdom.org

2.<<Processing XML with Java>> Elliotte Rusty Harold 2002

3.JDOM API Documentation

4.<<JDOM Makes XML Easy>>Jason Hunter Co-Creator JDOM Project

5.WSDP Tutorial

posted on 2006-09-14 11:09 周锐 阅读(172) 评论(0)  编辑  收藏 所属分类: Java

只有注册用户登录后才能发表评论。


网站导航: