xml檔案操作常用兩種方式:
一是jdom :特點,操作簡單,一般讀取常用,效率不高;
最近的工作常常要和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文檔。最後的結果(樣本文檔)看起來象這樣:
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就是類似上面樣本文檔中之間的東東,即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。
我們用同樣的方法添加帶屬性的子元素
rootElement.addContent(new Element("sex").setAttribute("value","male"));//注意這裡不需要轉型,因為addAttribute(String name,String value)傳回值就是一個 Element。
同樣的,我們添加元素到根元素下,用法上一樣,隻是稍微複雜了一些:
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;
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元素裡插入了一個新元素。盡管我們實作了對于XML的基本操作,細心的朋友可能會
有疑問:如果XML文檔的層次稍微複雜一些,如果嵌套多達幾十上百層的話(開個玩笑),如果靠這樣從根元素一級一級地通過getChild("childname")來通路子元素的話,将會非常痛苦!是的,的确是這樣,但是我們有另一個有力的工具XPath,為什麼不用呢?這是後話!先賣個關子(手敲累啦,下回吧,呵呵)。
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;
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","[email protected]"));
XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
String outStr = xmlOut.outputString(root);
System.out.println(outStr);
}
catch(Exception e)
{
e.printStackTrace();
}
}
} 評論這張
轉發至微網誌
轉發至微網誌
二是dom4j 特點,操作稍微複雜,讀取效率較高,對大批量讀取使用;
dom4j解析XML 2010-10-12 14:29:59| 分類: XML | 标簽: |字号大中小 訂閱 .
dom4j 是一種解析 XML 文檔的開放源代碼 XML 架構,與 W3C DOM API 相比,使用 dom4j 所包含的解析器的好處是 dom4j 擁有本地的 XPath 支援.DOM 解析器不支援使用 XPath 選擇節點.
該解析器可以從 http://dom4j.org/ 擷取.
java 代碼
java 代碼
package com.nikee.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.*;
public class XmlDom4J{
public void generateDocument(){
//使用 DocumentHelper 類建立一個文檔執行個體。 DocumentHelper 是生成 XML 文檔節點的 dom4j API 工廠類
Document document = DocumentHelper.createDocument();
//使用 addElement()方法建立根元素catalog , addElement()用于向 XML 文檔中增加元素
Element catalogElement = document.addElement("catalog");
//在 catalog 元素中使用 addComment() 方法添加注釋"An XML catalog"
catalogElement.addComment("An XML Catalog");
//在 catalog 元素中使用 addProcessingInstruction() 方法增加一個處理指令
catalogElement.addProcessingInstruction("target","text");
//在 catalog 元素中使用 addElement() 方法增加 journal 元素
Element journalElement = catalogElement.addElement("journal");
//使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 屬性
journalElement.addAttribute("title", "XML Zone");
journalElement.addAttribute("publisher", "IBM developerWorks");
Element articleElement=journalElement.addElement("article");
articleElement.addAttribute("level", "Intermediate");
articleElement.addAttribute("date", "December-2001");
Element titleElement=articleElement.addElement("title");
titleElement.setText("Java configuration with XML Schema");
Element authorElement=articleElement.addElement("author");
Element firstNameElement=authorElement.addElement("firstname");
firstNameElement.setText("Marcello");
Element lastNameElement=authorElement.addElement("lastname");
lastNameElement.setText("Vitaletti");
//可以使用 addDocType() 方法添加文檔類型說明
//這樣就向 XML 文檔中增加文檔類型說明:
document.addDocType("catalog","nikee","file://c:/Dtds/catalog.dtd");
try{
//XMLWriter output = new XMLWriter(new FileWriter( new File("D:/eclipse3.2/workspace/WebServices/src/com/nikee/dom4j/catalog.xml")));
FileOutputStream fos=new FileOutputStream("D:/eclipse3.2/workspace/WebServices/src/com/nikee/dom4j/catalog.xml");
OutputFormat of=new OutputFormat(" ", true);
XMLWriter xw=new XMLWriter(fos, of);
xw.write( document );
xw.close();
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] argv){
XmlDom4J dom4j=new XmlDom4J();
dom4j.generateDocument();
}
}
xml 代碼
xml 代碼
<!--sp-->xml version="1.0" encoding="UTF-8"?>
<!--CTYPE catalog PUBLIC "nikee" "file://c:/Dtds/catalog.dtd"</sp-->>
<catalog>
<!--An XML Catalog--><!--sp-->target text?>
<journal title="XML Zone" publisher="IBM developerWorks">
<article level="Intermediate" date="December-2001">
<title>Java configuration with XML Schematitle>
<author>
<firstname>Marcellofirstname>
<lastname>Vitalettilastname>
author>
article>
journal>
catalog>
XmlDom4J.java 用于建立 XML 文檔 catalog.xml
java 代碼
java 代碼
package com.nikee.dom4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Attribute;
import java.util.List;
import java.util.Iterator;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.*;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class Dom4Jparser{
public Dom4Jparser(){
//construction
}
public void modifyDocument(File inputXml){
try{
//使用 SAXReader 解析 XML 文檔 catalog.xml
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(inputXml);
//使用 XPath 表達式從 article 元素中獲得 level 節點清單。如果 level 屬性值是"Intermediate"則改為"Introductory"
List list = document.selectNodes("//article/@level");
Iterator iter=list.iterator();
while(iter.hasNext()){
Attribute attribute=(Attribute)iter.next();
if(attribute.getValue().equals("Intermediate"))
attribute.setValue("Introductory");
}
list = document.selectNodes("//article/@date" );
iter=list.iterator();
while(iter.hasNext()){
Attribute attribute=(Attribute)iter.next();
if(attribute.getValue().equals("December-2001"))
attribute.setValue("October-2002");
}
//擷取 article 元素清單,從 article 元素中的 title 元素得到一個疊代器,并修改 title 元素的文本
list = document.selectNodes("//article" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("title");
while(iterator.hasNext()){
Element titleElement=(Element)iterator.next();
if(titleElement.getText().equals("Java configuration with XML Schema"))
titleElement.setText("Create flexible and extensible XML schema");
}
}
list = document.selectNodes("//article/author" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("firstname");
while(iterator.hasNext()){
Element firstNameElement=(Element)iterator.next();
if(firstNameElement.getText().equals("Marcello"))
firstNameElement.setText("Ayesha");
}
}
list = document.selectNodes("//article/author" );
iter=list.iterator();
while(iter.hasNext()){
Element element=(Element)iter.next();
Iterator iterator=element.elementIterator("lastname");
while(iterator.hasNext()){
Element lastNameElement=(Element)iterator.next();
if(lastNameElement.getText().equals("Vitaletti"))
lastNameElement.setText("Malik");
}
}
FileOutputStream fos=new FileOutputStream("D:/eclipse3.2/workspace/WebServices/src/com/nikee/dom4j/catalog-modified.xml");
OutputFormat of=new OutputFormat(" ",true);
XMLWriter xw=new XMLWriter(fos, of);
xw.write( document );
xw.close();
}
catch(DocumentException e)
{
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
public static void main(String argv[]){
Dom4Jparser dom4jParser=new Dom4Jparser();
dom4jParser.modifyDocument(new File("D:/eclipse3.2/workspace/WebServices/src/com/nikee/dom4j/catalog.xml"));
}
}
xml 代碼
xml 代碼
<!--sp-->xml version="1.0" encoding="UTF-8"?>
<!--<!DOCTYPE catalog PUBLIC "nikee" "file://c:/Dtds/catalog.dtd">-->
<catalog>
<!--An XML Catalog--><!--sp-->target text?>
<journal title="XML Zone" publisher="IBM developerWorks">
<article level="Introductory" date="October-2002">
<title>Create flexible and extensible XML schematitle>
<author>
<firstname>Ayeshafirstname>
<lastname>Maliklastname>
author>
article>
journal>
catalog>
Dom4Jparser.java用于修改 XML 文檔 catalog.xml為catalog-modified.xml
問題總結:
1.當catalog.xml有<!--CTYPE catalog PUBLIC "nikee" "file://c:/Dtds/catalog.dt-->這一句,Dom4Jparser.java修改 XML 文檔 catalog.xml為catalog-modified.xml時,發生異常org.dom4j.DocumentException: c Nested exception: c.
原因:我自己沒有此file://c:/Dtds/catalog.dtd.
解決辦法:删掉此行.
2.除了加入dom4j.jar包外,必須加入jaxen.jar包,否則會發生異常.jaxen包可在http://jaxen.org/下載下傳.