JDOM 介绍及使用指南

JDOM 介绍及使用指南

一、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



在recs中的应用

      xml文件中配置了项目启动时要配置的文件,如mastercode,codebook等信息

例如:
resoue.xml
<?xml version="1.0" encoding="Shift_JIS"?>

<ResourceConfig>

    <!-- コードボック初期化処理 -->
    <Resource comment="コードボック">
        <Name>CodeBook</Name>
        <Reload>true</Reload>
        <Type>XML</Type>
        <File>jp/co/tr/com/config/CodeBook.xml</File>
        <Converter>jp.co.tr.com.resource.codebook.CodeBookConvert</Converter>
    </Resource>

    <!-- メッセージ初期化処理 -->
    <Resource comment="メッセージ">
        <Name>Message</Name>
        <Reload>true</Reload>
        <Type>PROPERTIES</Type>
        <File>jp/co/tr/com/config/message.properties</File>
        <Converter>jp.co.tr.com.resource.message.MessageConvert</Converter>
    </Resource>
</ResourceConfig>


  /**
     * <p>[名 称] XMLファイルの分析</p>
     * <p>[機 能] XMLファイルを分析する</p>
     *
     * @param is XMLファイル
     * @return List XMLファイルの情報
     * @throws IOException
     * @throws JDOMException
     */
    public List parse(InputStream is) throws TRSystemException {

        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(is);
            List children = load(doc);

            return children;
        } catch (Exception ie) {
            Message msg =
                new Message(
                    "MSG-E-CM0019",
                    "SYS00001",
                    TRException.convertThrowable(ie),
                    "");
            throw new TRSystemException(msg, ie);
        }
    }

    /**
     * <p>[名 称] XMLファイルのルートの分析</p>
     * <p>[機 能] XMLファイルのルートを分析する</p>
     *
     * @param doc XMLファイルのルート
     *
     * @return List XMLファイルの情報
     */
    private List load(Document doc) {

        Iterator it = doc.getRootElement().getChildren().iterator();
        List children = new ArrayList();

        while (it.hasNext()) {
            Element el = (Element) it.next();

            children.add(parseElement(el));
        }

        return children;
    }

    /**
     * <p>[名 称] Elementの分析</p>
     * <p>[機 能] Elementを分析する</p>
     *
     * @param el Element
     * @return ConfigNode Elementの情報
     */
    private ConfigNode parseElement(Element el) {

        ConfigNode node = new ConfigNode();

        node.setName(el.getName().toUpperCase());

        List attrList = el.getAttributes();

        if (attrList != null && attrList.size() > 0) {

            Iterator it = attrList.iterator();
            Attribute at = null;
            while (it.hasNext()) {
                at = (Attribute) it.next();
                node.putPropertie(at.getName().toUpperCase(), at.getValue());
            }
        }

        node.setContent(el.getText());


        List children = el.getChildren();

        if (children != null && children.size() > 0) {
            Iterator it = children.iterator();
            ConfigNode child = null;
            Element childEl = null;

            while (it.hasNext()) {
                childEl = (Element) it.next();
                child = parseElement(childEl);
                node.addChild(child);
            }
        }

        return node;
    }



/**
 * <p>[名 称] リソースの配置リスト</p>
 * <p>[機 能] リソースの配置リストとする</p>
 * <p>Copyright(c) SJNS 2004 2005</p>
 */
public class ConfigNode {

    /** 配置プロパティーマップ */
    HashMap propertiesMap = new HashMap();

    /** 配置項目内容 */
    String content = null;

    /** 名 */
    String name = null;

    /** 子配置項目 */
    List childList = null;

    /**
     * <p>[名 称] 子配置項目リストの取得</p>
     * <p>[機 能] 子配置項目リストを取得する</p>
     *
     * @return List 子配置項目リスト
     */
    public List getChildList() {
        return childList;
    }

    /**
     * <p>[名 称] 子配置項目リストの設定</p>
     * <p>[機 能] 子配置項目リストを設定する</p>
     *
     * @param childList 子配置項目リスト
     */
    public void setChildList(List childList) {
        this.childList = childList;
    }

    /**
     * <p>[名 称] 配置項目内容の取得</p>
     * <p>[機 能] 配置項目内容を取得する</p>
     *
     * @return String 配置項目内容
     */
    public String getContent() {
        return content;
    }

    /**
     * <p>[名 称] 配置項目内容の設定</p>
     * <p>[機 能] 配置項目内容を設定する</p>
     *
     * @param content 配置項目内容
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * <p>[名 称] プロパティーマップの取得</p>
     * <p>[機 能] プロパティーマップを取得する</p>
     *
     * @return HashMap プロパティーマップ
     */
    public HashMap getPropertiesMap() {
        return propertiesMap;
    }

    /**
     * <p>[名 称] プロパティーマップの設定</p>
     * <p>[機 能] プロパティーマップを設定する</p>
     *
     * @param propertiesMap プロパティーマップ
     */
    public void setPropertiesMap(HashMap propertiesMap) {
        this.propertiesMap = propertiesMap;
    }

    /**
     * <p>[名 称] プロパティーの追加</p>
     * <p>[機 能] プロパティーを追加する</p>
     *
     * @param key プロパティーキー
     * @param value プロパティー値
     */
    public void putPropertie(String key, String value) {
        propertiesMap.put(key, value);
    }

    /**
     * <p>[名 称] プロパティー値の取得</p>
     * <p>[機 能] プロパティー値を取得する</p>
     *
     * @param key プロパティーキー
     * @return String プロパティー値
     */
    public String getProperties(String key) {
        return (String) propertiesMap.get(key);
    }

    /**
     * <p>[名 称] 子配置項目の追加</p>
     * <p>[機 能] 子配置項目を追加する</p>
     *
     * @param node 子配置項目
     */
    public void addChild(ConfigNode node) {

        if (childList == null) {
            childList = new ArrayList();
        }

        childList.add(node);
    }

    /**
     * <p>[名 称] 配置項目名の取得</p>
     * <p>[機 能] 子配置項名を取得する</p>
     *
     * @return String 配置項目名
     */
    public String getName() {
        return name;
    }

    /**
     * <p>[名 称] 配置項目名の設定</p>
     * <p>[機 能] 子配置項名を設定する</p>
     *
     * @param name 配置項目名
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * <p>[名 称] 子配置項目の取得</p>
     * <p>[機 能] 子配置項目名を取得する</p>
     *
     * @param name 配置項目名
     * @return ConfigNode 子配置項目
     */
    public ConfigNode getChild(String name) {

        ConfigNode myChild = null;

        if (childList != null && childList.size() > 0) {

            Iterator it = childList.iterator();
            ConfigNode temp = null;

            while (it.hasNext()) {
                temp = (ConfigNode) it.next();
                if (name.equals(temp.getName())) {
                    myChild = temp;
                    break;
                }
            }
        }

        return myChild;
    }

    /**
     * <p>[名 称] 子配置項目の取得</p>
     * <p>[機 能] 子配置項目名を取得する</p>
     *
     * @param name 配置項目名
     * @return List 子配置項目
     */
    public List getChildren(String name) {

        List myChildren = new ArrayList();

        if (childList != null && childList.size() > 0) {
            Iterator it = childList.iterator();
            ConfigNode temp = null;

            while (it.hasNext()) {
                temp = (ConfigNode) it.next();
                if (name.equals(temp.getName())) {
                    myChildren.add(temp);
                }
            }
        }

        return myChildren;
    }
}


     



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值