最近的工作常常要和XML格式的文档或字符串打交道,发现用JDOM来做真是方便。可以实现XML应用程序的快速开发。
在 JDOM 中,XML 元素就是 Element 的实例,XML 属性就是 Attribute 的实例,XML 文档本身就是 Document 的实例。 因为 JDOM 对象就是像 Document、Element 和 Attribute 这些类的直接实例,因此创建一个新 JDOM 对象就如在 Java 语言中使用 new 操作符一样容易。JDOM 的使用是直截了当的。 JDOM 使用标准的 Java 编码模式。只要有可能,它使用 Java new 操作符而不故弄玄虚使用复杂的工厂化模式,使对象操作即便对于初学用户也很方便。 本文分两步对JDOM的应用加以介绍:XML创建 和 XML解析 一、XML文档创建 我们由零开始利用JDOM生成一个XML文档。最后的结果(样本文档)看起来象这样: <?xml version="1.0" encoding="UTF-8"?> <MyInfo comment="introduce myself"> <name>kingwong</name> <sex value="male"/> <contact> <telephone>87654321</telephone> </contact> </MyInfo> 1.以 MyInfo 为根元素创建文档 Element rootElement = new Element("MyInfo");//所有的XML元素都是 Element 的实例。根元素也不例外:) Document myDocument = new Document(rootElement);//以根元素作为参数创建Document对象。一个Document只有一个根,即root元素。 2.给根元素添加属性 Attribute rootAttri = new Attribute("comment","introduce myself");//创建名为 commnet,值为 introduce myself 的属性。 rootElement.setAttribute(rootAttri);//将刚创建的属性添加到根元素。 这两行代码你也可以合成一行来写,象这样: rootElement.setAttribute(new Attribute("comment","introduce myself")); 或者 rootElement.setAttribute("comment","introduce myself"); 3.添加元素和子元素 JDOM里子元素是作为 content(内容)添加到父元素里面去的,所谓content就是类似上面样本文档中<name></name>之间的东东,即kingwong。罗嗦了点是吧:) Element nameElement = new Element("name");//创建 name 元素 nameElement.addContent("kingwong");//将kingwong作为content添加到name元素 rootElement.addContent(nameElement);//将name元素作为content添加到根元素 这三行你也可以合为一句,象这样: rootElement.addContent((Content)(new Element("name").addContent("kingwong")));//因为addContent(Content child)方法返回的是一个Parent接口,而Element类同时继承了Content类和实现了Parent接口,所以我们把它造型成Content。 我们用同样的方法添加带属性的子元素<sex value="male"/> rootElement.addContent(new Element("sex").setAttribute("value","male"));//注意这里不需要转型,因为addAttribute(String name,String value)返回值就是一个 Element。 同样的,我们添加<contract />元素到根元素下,用法上一样,只是稍微复杂了一些: rootElement.addContent((Content)(new Element("contact").addContent((Content)(new Element("telephone").addContent("87654321"))))); 如果你对这种简写形式还不太习惯,你完全可以分步来做,就象本节刚开始的时候一样。事实上如果层次比较多,写成分步的形式更清晰些,也不容易出错。 4.删除子元素 这个操作比较简单: rootElement.removeChild("sex");//该方法返回一个布尔值 到目前为止,我们学习了一下JDOM文档生成操作。上面建立了一个样本文档,可是我们怎么知道对不对呢?因此需要输出来看一下。我们将JDOM生成的文档输出到控制台,使用 JDOM 的 XMLOutputter 类。 5. 将 JDOM 转化为 XML 文本 XMLOutputter xmlOut = new XMLOutputter(" ",true); try { xmlOut.output(myDocument,System.out); } catch (IOException e) { e.printStackTrace(); } XMLOutputter 有几个格式选项。这里我们已指定希望子元素从父元素缩进两个空格,并且希望元素间有空行。 new XMLOutputter(java.lang.String indent, boolean newlines)这个方法在最新版本中已经不建议使用。JDOM有一个专门的用来定义格式化输出的类:org.jdom.output.Format,如果你没有特殊的要求,有时候使用里面的几个静态方法(应该可以说是预定义格式)如 getPrettyFormat()就可以了。我们把上面的输出格式稍微改一下,就象这样: XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); 6.将JDOM文档转化为其他形式 XMLOutputter 还可输出到 Writer 或 OutputStream。为了输出JDOM文档到一个文本文件,我们可以这样做: FileWriter writer = new FileWriter("/some/directory/myFile.xml"); outputter.output(myDocument, writer); writer.close(); XMLOutputter 还可输出到字符串,以便程序后面进行再处理: Strng outString = xmlOut.outputString(myDocument); 当然,在输出的时候你不一定要输出所有的整个文档,你可以选择元素进行输出: xmlOut.output(rootElement.getChild("name"),System.out); 一句话,JDOM非常灵活方便!如果你想进一步研究JDOM,请到官方网站去看一看:http://www.jdom.org
本节示例源码: package com.cyberobject.study;
import java.io.IOException;
import org.jdom.Attribute; import org.jdom.Content; import org.jdom.Document; import org.jdom.Element; import org.jdom.output.Format; import org.jdom.output.XMLOutputter;
/** * @author kingwong * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class TestJDOM {
public static void main(String[] args) { Element rootElement = new Element("MyInfo"); Document myDocument = new Document(rootElement); // Attribute rootAttri = new Attribute("comment","introduce myself"); // rootElement.setAttribute(rootAttri); rootElement.setAttribute("comment","introduce myself"); //rootElement.setAttribute(new Attribute("comment","introduce myself")); // Element sexElement = new Element("sex"); // rootElement.addContent(sexElement); // Element nameElement = new Element("name"); // nameElement.addContent("kingwong"); // rootElement.addContent(nameElement); rootElement.addContent((Content)(new Element("name").addContent("kingwong"))); rootElement.addContent(new Element("sex").setAttribute("value","male")); rootElement.addContent((Content)(new Element("contract").addContent((Content)(new Element("telephone").addContent("87654321"))))); rootElement.removeChild("sex"); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); try { xmlOut.output(myDocument,System.out); //xmlOut.output(rootElement.getChild("name"),System.out); //String outString = xmlOut.outputString(myDocument); } catch (IOException e) { e.printStackTrace(); } } }
二、XML文档解析 JDOM 不光可以很方便的建立XML文档,它的另一个用处是它能够读取并操作现有的 XML 数据。 JDOM的解析器在org.jdom.input.*这个包里,其中的DOMBuilder的功能是将DOM模型的Document解析成JDOM模型的Document;SAXBuilder的功能是从文件或流中解析出符合JDOM模型的XML树。由于我们经常要从一个文件里读取数据,因此我们应该采用后者作为解析工具。 解析一个xml文档,基本可以看成以下几个步骤: 1.实例化一个合适的解析器对象 本例中我们使用SAXBuilder: SAXBuilder sb = new SAXBuilder(); 2.以包含XML数据的文件为参数,构建一个文档对象myDocument Document myDocument = sb.build(/some/directory/myFile.xml); 3.获到根元素 Element rootElement = myDocument.getRootElement(); 一旦你获取了根元素,你就可以很方便地对它下面的子元素进行操作了,下面对Element对象的一些常用方法作一下简单说明: getChild("childname") 返回指定名字的子节点,如果同一级有多个同名子节点,则只返回第一个;如果没有返回null值。 getChildren("childname") 返回指定名字的子节点List集合。这样你就可以遍历所有的同一级同名子节点。 getAttributeValue("name") 返回指定属性名字的值。如果没有该属性则返回null,有该属性但是值为空,则返回空字符串。 getChildText("childname") 返回指定子节点的内容文本值。 getText() 返回该元素的内容文本值。 还有其他没有罗列出来的方法,如果需要的话,可以随时查阅JDOM的在线文档:http://www.jdom.org/docs/apidocs/index.html。当然你可以在你需要的地方添加、删除元素操作,还记得上面的创建XML的方法吗?呵呵~~~ 学习新东东还是从实例学起最为快捷,下面简单举个例子,就以上面的XML样本代码来学习JDOM的XML解析。本例中读取了样本XML文件里一些属性和content,最后我们还在contact元素里插入了一个新元素<email value="wanghua@cyberobject.com" />。尽管我们实现了对于XML的基本操作,细心的朋友可能会 有疑问:如果XML文档的层次稍微复杂一些,如果嵌套多达几十上百层的话(开个玩笑),如果靠这样从根元素一级一级地通过getChild("childname")来访问子元素的话,将会非常痛苦!是的,的确是这样,但是我们有另一个有力的工具XPath,为什么不用呢?这是后话!先卖个关子(手敲累啦,下回吧,呵呵)。 /* * Created on 2004-8-21 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package com.cyberobject.study;
import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter;
/** * @author kingwong * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class TestJDOM2 { public static void main(String[] args){ SAXBuilder sb = new SAXBuilder(); try { Document doc = sb.build("myFile.xml"); Element root = doc.getRootElement(); String str1 = root.getAttributeValue("comment"); System.out.println("Root Element's comment attribute is : " + str1); String str2 = root.getChild("sex").getAttributeValue("value"); System.out.println("sex Element's value attribute is : " + str2); String str3 = root.getChildText("name"); System.out.println("name Element's content is :" + str3); String str4 = root.getChild("contact").getChildText("telephone"); System.out.println("contact Element's telephone subelement content is : " + str4 + "\n"); Element inputElement = root.getChild("contact"); inputElement.addContent(new Element("email").setAttribute("value","wanghua@cyberobject.com")); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); String outStr = xmlOut.outputString(root); System.out.println(outStr); } catch(Exception e) { e.printStackTrace(); } } }
|