在項目中,我們很多都用到了xml檔案,無論是參數配置還是與其它系統的資料互動。 今天就來講一下Java 中使用dom4j來操作XML檔案。 我們需要引入的包: //檔案包 import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileWriter; //工具包 import java.util.Iterator; import java.util.List; //dom4j包 import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; 1、将XML檔案的内容轉化為String /** * doc2String * 将xml文檔内容轉為String * @return 字元串 * @param document */ public static String doc2String(Document document) { String s = ""; try { //使用輸出流來進行轉化 ByteArrayOutputStream out = new ByteArrayOutputStream(); //使用GB2312編碼 OutputFormat format = new OutputFormat(" ", true, "GB2312"); XMLWriter writer = new XMLWriter(out, format); writer.write(document); s = out.toString("GB2312"); }catch(Exception ex) { ex.printStackTrace(); } return s; } 2、将符合XML格式的String 轉化為XML Document * string2Document * 将字元串轉為Document * @return * @param s xml格式的字元串 public static Document string2Document(String s) Document doc = null; doc = DocumentHelper.parseText(s); } return doc; 3、将Document對象儲存為一個xml檔案到本地 * doc2XmlFile * 将Document對象儲存為一個xml檔案到本地 * @return true:儲存成功 flase:失敗 * @param filename 儲存的檔案名 * @param document 需要儲存的document對象 public static boolean doc2XmlFile(Document document,String filename) boolean flag = true; /* 将document中的内容寫入檔案中 */ //預設為UTF-8格式,指定為"GB2312" OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("GB2312"); XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format); writer.write(document); writer.close(); }catch(Exception ex) { flag = false; ex.printStackTrace(); } return flag; 4、将xml格式的字元串儲存為本地檔案,如果字元串格式不符合xml規則,則傳回失敗 * string2XmlFile * 将xml格式的字元串儲存為本地檔案,如果字元串格式不符合xml規則,則傳回失敗 * @param str 需要儲存的字元串 public static boolean string2XmlFile(String str,String filename) Document doc = DocumentHelper.parseText(str); flag = doc2XmlFile(doc,filename); }catch (Exception ex) flag = false; ex.printStackTrace(); return flag; 5、載入一個xml文檔 * load * 載入一個xml文檔 * @return 成功傳回Document對象,失敗傳回null * @param uri 檔案路徑 public static Document load(String filename) Document document = null; try { SAXReader saxReader = new SAXReader(); document = saxReader.read(new File(filename)); filename = "E://11.txt" catch (Exception ex){ ex.printStackTrace(); } return document; 6、示範String儲存為xml檔案 * xmlWriteDemoByString * 示範String儲存為xml檔案 public void xmlWriteDemoByString() /** xml格式标題 "<?xml version='1.0' encoding='GB2312'?>" 可以不用寫*/ s = "<config>\r\n" +" <ftp name='DongDian'>\r\n" +" <ftp-host>127.0.0.1</ftp-host>\r\n" +" <ftp-port>21</ftp-port>\r\n" +" <ftp-user>cxl</ftp-user>\r\n" +" <ftp-pwd>longshine</ftp-pwd>\r\n" +" <!-- ftp最多嘗試連接配接次數 -->\r\n" +" <ftp-try>50</ftp-try>\r\n" +" <!-- ftp嘗試連接配接延遲時間 -->\r\n" +" <ftp-delay>10</ftp-delay>\r\n" +" </ftp>\r\n" +"</config>\r\n"; //将檔案生成到classes檔案夾所在的目錄裡 string2XmlFile(s,"xmlWriteDemoByString.xml"); //将檔案生成到classes檔案夾裡 string2XmlFile(s,"classes/xmlWriteDemoByString.xml"); 7、示範手動建立一個Document,并儲存為XML檔案 * 示範手動建立一個Document,并儲存為XML檔案 public void xmlWriteDemoByDocument() /** 建立document對象 */ Document document = DocumentHelper.createDocument(); /** 建立config根節點 */ Element configElement = document.addElement("config"); /** 建立ftp節點 */ configElement.addComment("東電ftp配置"); Element ftpElement = configElement.addElement("ftp"); ftpElement.addAttribute("name","DongDian"); /** ftp 屬性配置 */ Element hostElement = ftpElement.addElement("ftp-host"); hostElement.setText("127.0.0.1"); (ftpElement.addElement("ftp-port")).setText("21"); (ftpElement.addElement("ftp-user")).setText("cxl"); (ftpElement.addElement("ftp-pwd")).setText("longshine"); ftpElement.addComment("ftp最多嘗試連接配接次數"); (ftpElement.addElement("ftp-try")).setText("50"); ftpElement.addComment("ftp嘗試連接配接延遲時間"); (ftpElement.addElement("ftp-delay")).setText("10"); /** 儲存Document */ doc2XmlFile(document,"classes/xmlWriteDemoByDocument.xml"); 8、示範讀取檔案的具體某個節點的值 * 示範讀取檔案的具體某個節點的值 public static void xmlReadDemo() Document doc = load("classes/xmlWriteDemoByDocument.xml"); //Element root = doc.getRootElement(); /** 先用xpath查找所有ftp節點 并輸出它的name屬性值*/ List list = doc.selectNodes("/config/ftp" ); Iterator it = list.iterator(); while(it.hasNext()) { Element ftpElement = (Element)it.next(); System.out.println("ftp_name="+ftpElement.attribute("name").getValue()); /** 直接用屬性path取得name值 */ list = doc.selectNodes("/config/ftp/@name" ); it = list.iterator(); Attribute attribute = (Attribute)it.next(); System.out.println("@name="+attribute.getValue()); /** 直接取得DongDian ftp的 ftp-host 的值 */ list = doc.selectNodes("/config/ftp/ftp-host" ); Element hostElement=(Element)it.next(); System.out.println("DongDian's ftp_host="+hostElement.getText()); 9、修改或删除某個值或屬性 /** ftp節點删除ftp-host節點 */ ftpElement.remove(hostElement); /** ftp節點删除name屬性 */ ftpElement.remove(nameAttribute); /** 修改ftp-host的值 */ hostElement.setText("192.168.0.1"); /** 修改ftp節點name屬性的值 */ nameAttribute.setValue("ChiFeng"); |
dom4j(Version 1.6.1)快速入門
Parsing XML
或許你想要做的第一件事情就是解析一個某種類型的XML文檔,用dom4j很容易做到。請看下面的示範代碼:
import java.net.URL;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class Foo {
public Document parse(URL url) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(url);
return document;
}
}
使用疊代器(Iterators)
我們可以通過多種方法來操作XML文檔,這些方法傳回java裡标準的疊代器(Iterators)。例如:
public void bar(Document document) throws DocumentException {
Element root = document.getRootElement();
//疊代根元素下面的所有子元素
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
//處理代碼
}
//疊代根元素下面名稱為"foo"的子元素
for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) {
Element foo = (Element) i.next();
// 疊代根元素的屬性attributes)元素
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
// do something
}
強大的XPath導航
在dom4j中XPath可以表示出在XML樹狀結構中的Document或者任意的節點(Node)(例如:Attribute,Element 或者ProcessingInstruction等)。它可以使在文檔中複雜的操作僅通過一行代碼就可以完成。例如:
public void bar(Document document) {
List list = document.selectNodes( "//foo/bar" );
Node node = document.selectSingleNode( "//foo/bar/author" );
String name = node.valueOf( "@name" );
如果你想得到一個XHTML文檔中的所有超文本連結(hypertext links)你可以使用下面的代碼:
public void findLinks(Document document) throws DocumentException {
List list = document.selectNodes( "//a/@href" );
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
Attribute attribute = (Attribute) iter.next();
String url = attribute.getValue();
如果你需要關于XPath語言的任何幫助,我們強烈推薦這個站點
Zvon tutorial他會通過一個一個的例子引導你學習。
快速周遊(Fast Looping)
如果你不得不周遊一個非常大的XML文檔,然後才去執行,我們建議你使用快速周遊方法(fast looping method),它可以避免為每一個循環的節點建立一個疊代器對象,如下所示:
public void treeWalk(Document document) {
treeWalk( document.getRootElement() );
public void treeWalk(Element element) {
for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
Node node = element.node(i);
if ( node instanceof Element ) {
treeWalk( (Element) node );
}
else {
// do something....
生成一個新的XML文檔對象
在dom4j中你可能常常希望用程式生成一個XML文檔對象,下面的程式為你進行了示範:
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
public Document createDocument() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement( "root" );
Element author1 = root.addElement( "author" )
.addAttribute( "name", "James" )
.addAttribute( "location", "UK" )
.addText( "James Strachan" );
Element author2 = root.addElement( "author" )
.addAttribute( "name", "Bob" )
.addAttribute( "location", "US" )
.addText( "Bob McWhirter" );
将一個文檔對象寫入檔案中
将一個文檔對象寫入Writer對象的一個簡單快速的途徑是通過write()方法。
FileWriter out = new FileWriter( "foo.xml" );
document.write( out );
如果你想改變輸出檔案的排版格式,比如你想要一個漂亮的格式或者是一個緊湊的格式,或者你想用Writer 對象或者OutputStream 對象來操作,那麼你可以使用XMLWriter 類。
import org.dom4j.io.OutputFormat;
public void write(Document document) throws IOException {
// 寫入檔案
XMLWriter writer = new XMLWriter(
new FileWriter( "output.xml" )
);
writer.write( document );
writer.close();
// 以一種優雅的格式寫入System.out對象
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter( System.out, format );
// 以一種緊湊的格式寫入System.out對象
format = OutputFormat.createCompactFormat();
轉化為字元串,或者從字元串轉化
如果你有一個文檔(Document)對象或者任何一個節點(Node)對象的引用(reference),象屬性(Attribute)或者元素(Element),你可以通過asXML()方法把它轉化為一個預設的XML字元串:
Document document = ...;
String text = document.asXML();
如果你有一些XML内容的字元串表示,你可以通過DocumentHelper.parseText()方法将它重新轉化為文檔(Document)對象:
String text = "<person> <name>James</name> </person>";
Document document = DocumentHelper.parseText(text);
通過XSLT樣式化文檔(Document)
使用Sun公司提供的
JAXPAPI将XSLT 應用到文檔(Document)上是很簡單的。它允許你使用任何的XSLT引擎(例如:Xalan或SAXON等)來開發。下面是一個使用JAXP建立一個轉化器(transformer),然後将它應用到文檔(Document)上的例子:
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
public Document styleDocument(
Document document,
String stylesheet
) throws Exception {
// 使用 JAXP 加載轉化器
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(
new StreamSource( stylesheet )
// 現在來樣式化一個文檔(Document)
DocumentSource source = new DocumentSource( document );
DocumentResult result = new DocumentResult();
transformer.transform( source, result );
// 傳回經過樣式化的文檔(Document)
Document transformedDoc = result.getDocument();
return transformedDoc;
閱讀(965