一、需求
有兩個部門,部門A和部門B,部門B需要部門A提供一些數據,而這些數據存放在部門A的數據庫中(這些數據會不定期的更新),要求將這些數據的變更(主要是添加)定期自動從部門A 的數據庫導入到部門B的數據庫中。注意:部門A的數據庫和部門B的數據庫不是統一的。
二、分析
要實現這個功能,最平常的想法就是:從部門A的數據庫中獲取這些數據,然後將這些數據導入到部門B的數據庫中。下面是對這兩個步驟的仔細分析。
1)從部門A的數據庫中取得數據
分析:在部門A架設一個網站,這個網站的功能很簡單:從部門A的數據庫中讀取數據,並顯示在頁面上。
2)取得網站上的數據,並將這些數據導入到部門B的數據庫中
分析:分為以下幾個步驟:
1 ) 要實現自動定期的導入,我們需要設計一個Windows服務定期訪問架設在部門A的網站,並從頁面上讀取數據。
2)要將這些數據導入到部門B的數據庫中,就要將這些數據進行解析,是指滿足部門B的數據庫的格式。因為部門A和部門B的數據庫是不統一的。
3) 完成上面兩部後, 將解析好的數據導入到部門B的數據庫中。
難點:部門A的數據以一種什麼樣的格式顯示在網站上,才能更好的被讀取,解析成部門B所需要的數據呢?這是我想到了XML:將部門A的數據以XML的格式顯示在網站的頁面上,部門B獲取這些XML,解析XML,最後就能獲取這些數據。
綜上,要實現這個功能,我們需要一下三個步驟
1)在部門A架設一網站,將數據以XML的格式顯示在網站的頁面上。
2)設計一Windows服務,定期訪問這個網站,取得xml,在對這個XML進行解析,獲得需要的數據。
3) 將這些數據導入到部門B的數據庫中。
三、實現
1)部門A架設一網站,將數據以XML的格式顯示在網站的頁面上。
這個網站是非常簡單的,一個頁面,沒有任何業務邏輯,就是將取出數據,然後拼成XML的格式,顯示在頁面上。
如何具體實現就不多說了,就是根據給定的XML的形式,拼字符串,下面是我XML的格式,title是對數據的描述,value的數據的值。
<EntitIEs>
<Entity>
<Itemtitle="****"value="***"/>
<Itemtitle="****"value="***"/>
<Itemtitle="****"value="***"/>
</Entity>
</EntitIEs>
2)設計一Windows服務,訪問這個網站,讀取數據,解析數據。
這一步,主要說下從頁面中獲取xml,並解析XML。至於如何建Windows服務這裡就不說了,相信大家都很熟悉。
1>從頁面中獲取XML類,看代碼:
///<summary>
///從頁面中獲得XML文檔
///</summary>
publicclassGetXMLDocFromWeb
{///<summary>
///獲得XML文檔
///</summary>
///<returns></returns>
publicstaticXmlDocumentLoadXMLDocument(stringurl)
{
StreamReaderstreamReader=GetWebContent(url);
XmlDocumentxdoc=newXMLDocument();
xdoc.Load(streamReader);
returnxdoc;
}
privatestaticStreamReaderGetWebContent(stringUrl)
{
//聲明一個HttpWebRequest請求
HttpWebRequestrequest=(HttpWebRequest)WebRequest.Create(Url);
//設置連接超時時間
request.Timeout=300000;
request.Headers.Set("Pragma","no-cache");
HttpWebResponseresponse=(HttpWebResponse)request.GetResponse();
StreamstreamReceive=response.GetResponseStream();
Encodingencoding=Encoding.GetEncoding("utf-8");
StreamReaderstreamReader=newStreamReader(streamReceive,encoding);
returnstreamReader;
}
}
這個類接收一個url(網站的地址)參數,返回一個XML文檔。
2> 獲得xml文檔後,對這個XML文檔進行解析,(文檔格式在上文中已給出)
從上面的文檔格式我們可以看出,這一文檔有許多Entity,每個Entity有許多Item,每個Item又有title和value屬性,因此抽象出兩個列:EntityImporter和ItemImporter。代碼如下:
首先是EntityImporter類:
///<summary>
///要導入的數據
///</summary>
publicclassEntityImport
{
privateList<ItemImport>_ItemList=newList<ItemImport>();
///<summary>
///導入數據的詳細信息
///</summary>
publicList<ItemImport>ItemList
{
get{return_ItemList;}
set{_ItemList=value;}
}
}
然後是ItemImporter類:
///<summary>
///導入數據詳細信息
///</summary>
publicclassItemImport
{
///<summary>
///名稱屬性
///</summary>
publicstringTitle{get;set;}
///<summary>
///值屬性
///</summary>
publicstringValue{get;set;}
}
有了這兩類後,就可以對XML進行解析,代碼如下:
///<summary>
///解析XML文檔
///</summary>
///<paramname="xdoc"></param>
///<paramname="rootNode"></param>
///<returns></returns>
publicstaticList<EntityImport>parseXmlDocument(XMLDocumentxdoc,stringrootNode)
{
List<EntityImport>EntityImportList=newList<EntityImport>();
foreach(XmlNodeXMLNodeinxdoc.SelectSingleNode(rootNode).ChildNodes)
{
if(XMLNode!=null)
{
EntityImportentityImport=newEntityImport();
EntityImportList.Add(entityImport);
foreach(XmlNodenodeinXMLNode.ChildNodes)
if(node!=null)
entityImport.ItemList.Add(getItemFromNode(node));
}
}
returnEntityImportList;
}
privatestaticItemImportgetItemFromNode(XMLNodenode)
{
ItemImportitem=newItemImport();
item.Title=getStringFromAttribute(node,"title");
item.Value=getStringFromAttribute(node,"value");
returnitem;
}
privatestaticstringgetStringFromAttribute(XMLNodenode,stringAttributeName)
{
if(node.Attributes[AttributeName]==null)
returnstring.Empty;
else
returnnode.Attributes[AttributeName].Value;
}
}
這樣我們將XML解析成一個list,就可以非常方便的遍歷這個list取得數據。取得數據後,就可以導入到數據庫了。
3> 導入數據
要導入數據,首先要取得數據庫,考慮到數據庫可能會變,我們將數據庫的連接字符串放在了注冊表文件中,這樣就不用擔心數據庫的變化。
取得數據庫的代碼如下:
///<summary>
///取得數據庫
///</summary>
publicclassGetDataBase
{
privateconststringRegPath=@"SOFTWARESrimsDatabaseConnectionString";
privateconststringConnectionStringKey="connectionString";
///<summary>
///取得數據庫
///</summary>
///<returns></returns>
publicstaticDatabaseGetNewDataBase()
{
stringconnectionString=getConnectionString();
Databasedatabase=Database.New(connectionString);
returndatabase;
}
privatestaticstringgetConnectionString()
{
returnRegistry
.LocalMachine
.OpenSubKey(RegPath)
.GetValue(ConnectionStringKey)
.ToString();
}
}
好,這樣數據導入前的工作就算完成了,導入數據的過程就不說了,這是最簡單的部分了。
四、總結
這個功能的核心就是取得XML文檔,並對其進行解析。實現了這兩個功能,一切都變得簡單了。