xml|程式|資料|資料庫 總是在網路上copy別人的原始碼,今天我也貼出自己今天寫的源碼,相信這個程式會對大家在平時的工作中需要頻繁從資料庫中提取資料轉化成xml檔案會有協助。
最近公司項目中有一件事就是從資料庫表中讀出資料,然後轉換成xml檔案供用戶端下載,由於資料庫中表太多,不可能為單獨的每個表都寫一個轉換程式。於是,經過分析,寫了一個通用的用ResultSet對象轉換成xml檔案的程式。這樣,只需把查詢結果集(ResultSet對象)和要產生的xml檔案的路徑傳入,然後自己指派屬性名稱、元素名稱並與對應的查詢結果集中的欄位相對應,最後調用designOver()函數,就可以產生所期望的xml檔案了。最後,給出了一個樣本程式。
我是用dom解析的,用純java語言編寫,程式包括5個類:CreateXmlFile.java、Disposal.java、SaveAttrName.java、SaveEleName.java、WriteXmlFile.java
真正與使用者互動的只有CreateXmlFile.java,如果不想瞭解程式邏輯,可不用管其他類。代碼講解及樣本如下:
檔案 CreateXmlFile.java 內容:
package currencycreatexml;
import java.sql.*;
public class CreateXmlFile
{
private ResultSet rs; //從下面的程式可以看出,此欄位可省略,懶得改了,呵呵
private String url; //從下面的程式可以看出,此欄位可省略,懶得改了,呵呵
private Disposal disposal; //自訂的用來收集和處理資料的類
private String root; //xml檔案的根項目名稱
private String rootchild; //根結點的子結點的元素名稱
/**
* @param rs : 建立xml檔案所需的查詢結果集
* @param url : 指定xml檔案的產生路徑(包括xml檔案的檔案名稱)
*/
public CreateXmlFile(ResultSet rs,String url)
{
this.rs=rs;
this.url=url;
disposal=new Disposal();
disposal.setResultSet(this.rs,this.url);
}
//設定xml檔案的根項目名稱
public void setRootElementName(String root,String rootchild)
{
this.root=root;
this.rootchild=rootchild;
disposal.setRootName(this.root,this.rootchild);
}
//設定屬性的名字和索引位置,位置從1開始
/**
* @param namestring 指定屬性的名稱
* @param index 指定此屬性的值在查詢結果集中第幾個欄位(欄位從1開始索引)
*/
public void setAttributeName(String namestring,int index)
{
disposal.collectData(namestring,index,"attribute");
}
//設定元素的名字和索引位置,位置從1開始
/**
* @param namestring 指定元素的名稱
* @param index 指定此元素的值在查詢結果集中的第幾個欄位(欄位從1開始索引)
*/
public void setElementName(String namestring,int index)
{
disposal.collectData(namestring,index,"element");
}
/**
* 調用此方法則立即開始建立xml檔案,在屬性與元素都已指派完畢後調用此方法
*/
public void designOver()
{
disposal.startWrite();
}
}
檔案 Disposal.java 內容:
package currencycreatexml;
import java.util.*;
import java.sql.*;
class Disposal
{
private ResultSet rs;
private String url;
private ArrayList attrilist=new ArrayList(); //用來儲存屬性名稱和欄位索引的集合類
private ArrayList elelist=new ArrayList(); //用來儲存元素名和欄位索引的集合類
private String root;
private String rootchild;
public void setResultSet(ResultSet rs,String url)
{
this.rs=rs;
this.url=url;
}
public void setRootName(String root,String rootchild)
{
this.root=root;
this.rootchild=rootchild;
}
@SuppressWarnings("unchecked")
public void collectData(String namestring,int index,String type )
{
if(type.equals("attribute"))
attrilist.add(new SaveAttrName(namestring,index));
else
elelist.add(new SaveEleName(namestring,index));
//System.out.println("else");
//System.exit(0);
}
public void startWrite()
{
new WriteXmlFile(attrilist,elelist,rs,url).create(root,rootchild);
}
}
檔案 SaveAttrName.java 內容:
package currencycreatexml;
class SaveAttrName
{
private String attributename;
private int index;
public SaveAttrName(String attributename,int index)
{
this.attributename=attributename;
this.index=index;
}
public String getAttributeName()
{
return attributename;
}
public int getIndex()
{
return index;
}
}
檔案 SaveEleName.java 內容:
package currencycreatexml;
class SaveEleName
{
private String elementname;
private int index;
public SaveEleName(String elementname,int index)
{
this.elementname=elementname;
this.index=index;
}
public String getElementName()
{
return elementname;
}
public int getIndex()
{
return index;
}
}
檔案 WriteXmlFile.java 內容:
package currencycreatexml;
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.parsers.*;
import org.w3c.dom.*; //使用dom解析
import org.apache.crimson.tree.*; //寫xml檔案需要用到的jar包
class WriteXmlFile
{
private ResultSet rs;
private String url;
private ArrayList attrilist;
private ArrayList elelist;
public WriteXmlFile(ArrayList attrilist,ArrayList elelist,ResultSet rs,String url)
{
this.attrilist=attrilist;
this.elelist=elelist;
this.rs=rs;
this.url=url;
}
/**
* @param root : xml檔案的根項目名
*/
public void create(String root,String rootchild)
{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
Document doc=null;
try
{
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.newDocument();
}
catch (ParserConfigurationException e)
{
e.printStackTrace();
}
Element rootelement=doc.createElement(root);
doc.appendChild(rootelement);
Iterator attri=attrilist.iterator();
Iterator ele=elelist.iterator();
//System.out.println("iterator");
try
{
while(rs.next())
{
Element rootchildelement=doc.createElement(rootchild);
//System.out.println("while");
while(attri.hasNext())
{
/**
* 迴圈到屬性集合中取元素名稱,之後從查詢結果集中取得資料,建立元素屬性
*/
SaveAttrName temp=(SaveAttrName)attri.next();
rootchildelement.setAttribute(temp.getAttributeName(),rs.getString(temp.getIndex()).trim());
}
rootelement.appendChild(rootchildelement);
while(ele.hasNext())
{
/**
* 迴圈到元素集合中取元素名稱,之後從查詢結果集中取得資料,建立結點
*/
SaveEleName temp=(SaveEleName)ele.next();
Element tempelement=doc.createElement(temp.getElementName());
Text temptextelement=doc.createTextNode(rs.getString(temp.getIndex()).trim());
tempelement.appendChild(temptextelement);
rootchildelement.appendChild(tempelement);
}
attri=attrilist.iterator(); //重複迴圈到集合中取值,下同
ele=elelist.iterator();
}
}
catch (Exception e)
{
e.printStackTrace();
}
writeXml(doc);
}
private void writeXml(Document doc)
{
try
{
FileOutputStream outStream = new FileOutputStream(url);
OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
((XmlDocument)doc).write(outWriter, "GB2312");
outWriter.close();
outStream.close();
System.out.print("\nWrite xmlfile successful!\n");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
講解:
假設資料庫中有一個表,表名為“CCNUstudents”,
表中有幾條記錄,現將它轉換為xml檔案,我轉換的規則為將記錄的關鍵字作為元素的屬性,其它作為了結點。當然,你也可以以自己的規則將資料庫中的任何欄位設定為屬性或元素。所有元素及屬性的名稱可以自訂,表中的內容為:
學號 姓名 學校 系別 家庭住址
20033274 邪 華中師範大學 資訊管理系 湖北省監利縣龔場鎮
20043225 阿維 中南民族大學 經濟系 湖北省監利縣周老咀鎮
假設關鍵字段為“學號”,則可將此錶轉換為一個xml檔案:
範例程式碼如下:
檔案 test.java 中測試函數的內容:
public static void main(String[] args) throws Exception
{
SQLExecute conn=new SQLExecute();
ResultSet rs=conn.sqlQuery("select * from CCNUstudents");
CreateXmlFile create = new CreateXmlFile(rs,"demo.xml");
create.setRootElementName("學生基本資料","學生");
create.setAttributeName("學生學號",1);
create.setElementName("學生的姓名",2);
create.setElementName("所在學校",3);
create.setElementName("所在系",4);
create.setElementName("住址",5);
create.designOver();
}
函數setAttributeName(String,int)及setElementName(String,int)中的String用來指定元素名或是屬性名稱,int型數字用來關聯此元素或屬性的值是從表中的第幾個欄位取出來的。程式運行結果後,就會在目前的目錄下產生一個名為“demo.xml”的xml檔案,檔案內容為:
<?xml version="1.0" encoding="GB2312"?>
<學生基本資料>
<學生 學生學號="20033274">
<學生的姓名>邪</學生的姓名>
<所在學校>華中師範大學</所在學校>
<所在系>資訊管理</所在系>
<住址>湖北省監利縣龔場鎮</住址>
</學生>
<學生 學生學號="20043225">
<學生的姓名>阿維</學生的姓名>
<所在學校>中南民族大學</所在學校>
<所在系>經濟系</所在系>
<住址>湖北省監利縣周老咀鎮</住址>
</學生>
</學生基本資料>
當然,如果資料表中有多個關鍵字,也可以在程式中指定多個屬性。
至此,一個xml檔案就產生了。當然,為求程式簡便,關於xml檔案中的命名空間、CDATA都沒有作處理。希望可以起到拋磚引玉的作用。
程式流程及邏輯可以參看類中的注釋~。
(-小邪(QQ:156411203,歡迎交流)-2006.7.21)。
最後補充一點,你並不需要為每一個查詢結果集中的欄位都指派相應的元素或屬性名稱,而只需根據你自己的需要,為你想要儲存到xml檔案中的那些欄位指派名稱就可以了,最後,別忘記了調用designOver()函數,告訴程式表示已經指派完畢了!'
註:本文轉自http://bbs.xml.org.cn/dispbbs.asp?boardID=17&replyID=75002&ID=41933&skin=1