好得文西
我們說到怎麼組字串,請看VCR前情提要(跳)
好啦我也不記得上次說到哪,自己開一下上一篇
ㄏㄏ。
直接進入重點提要
var Today = DateTime.Now.ToString("yyyyMMdd");
//這邊抓取系統上顯示的時間,並且轉為字串,表現形式為年年年年月月天天 ,以現在為例就是 Today就會等於20180818
var Now = DateTime.Now.ToString("HHmm");//請不要把mm打成MM,會變成月 吧 不確定 反正會有BUG 顆顆
//這邊就是抓取當下的時間並且轉為字串,表現形式為時時分分 比如洞六洞洞部隊起床~~~~~~~~~~
回到上次提到的,假如我每五分鐘要抓一次檔案(比如我稍後舉例的網站他是每五分鐘產生一次XML檔)
那麼就得設法讓我組的字串可以正確判斷時間,才能抓到該檔案。
int IntNowData =( (Convert.ToInt32(Now) / 5) * 5);//把取得的NOW從字串轉成int,才能進行計算
string GetNowData = Convert.ToString(IntNowData).PadLeft(4,'0');//總數四位,不足補'0'
//把計算後的int 也就是IntNowData轉為string存進GetNowData,等等會用到
============程式碼區域
XmlDocument RoadSpeeddoc = new XmlDocument();//用來抓路段靜態資訊
XmlDocument RoadSpeeddoc2 = new XmlDocument();//用來抓服務水準門檻分級
XmlDocument RoadSpeeddoc3 = new XmlDocument();//用來抓路段動態資訊
tring Constr = "server=.;database=TEST;integrated security=SSPI"; //開啟SQL連線,這個用法是本機登入
SqlConnection conn = new SqlConnection(Constr);
conn.Open();
這次要抓的資料呢,是以這個網址的XML檔案為主。http://59.120.122.53/xmlfile/
舉例的相關路徑可以直接複製下面三個目標網址,進去看一下。
我要做的事情是把這三個XML的資料寫進同一張Table裡面,稍後會提到關聯性的語法,讓程式碼不用滴血就可以認親。
目標網址:http://59.120.122.53/xmlfile/roadlevel/2018/roadlevel_info_0000.xml
string GetDataUrl_StaticData_Road = "http://59.120.122.53/xmlfile/roadlevel/" + Today + "/roadlevel_info_0000.xml";//路段靜態資訊組字串 不會變動
RoadSpeeddoc.Load(GetDataUrl_StaticData_Road);//取得路段靜態資訊 根據檔案產生的時間及我的需求=>一天抓一次
XmlNodeList RoadSpeedNodeLists = RoadSpeeddoc.SelectNodes("XML_Head/Infos/Info");
*XML_Head/Infos/Info //讀取節點資訊,這個用法要查一下,我也不是很熟 可以觀察一下上述網址的結構
目標網址:http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_threshold_0000.xml
string GetDataUrl_ServiceLevel = "http://59.120.122.53/xmlfile/roadlevel/" + Today + "/roadlevel_threshold_0000.xml";//服務水準門檻分級組字串
RoadSpeeddoc2.Load(GetDataUrl_ServiceLevel);//取得服務水準門檻分級資訊 根據檔案產生的時間及我的需求=>一天抓一次
XmlNodeList RoadSpeedNodeLists2 = RoadSpeeddoc2.SelectNodes("XML_Head/Infos/Info");
目標網址:http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_value_0800.xml
string GetDataUrl = "http://59.120.122.53/xmlfile/roadlevel/" + Today + "/roadlevel_value_" + GetNowData + ".xml";//路段動態資訊組字串
RoadSpeeddoc3.Load(GetDataUrl);//取得路段動態資訊,根據檔案產生的時間及我的需求=>五分鐘抓一次
XmlNodeList RoadSpeedNodeLists3 = RoadSpeeddoc3.SelectNodes("XML_Head/Infos/Info");
接著呢,就需要到SQL資料庫裡面建立資料表來儲存資料
建立好資料表之後呢,回到程式 馬的 部分。
//路段靜態資訊http://59.120.122.53/xmlfile/roadlevel/2018/roadlevel_info_0000.xml 起點
string GetDataUrl_StaticData_Road = "http://59.120.122.53/xmlfile/roadlevel/" + Today + "/roadlevel_info_0000.xml";
RoadSpeeddoc.Load(GetDataUrl_StaticData_Road);
XmlNodeList RoadSpeedNodeLists = RoadSpeeddoc.SelectNodes("XML_Head/Infos/Info");
string DeleteSpeedXmlData = "Delete from dbo.RoadSpeedXml"; //我希望每次執行的時候,都先清除掉原有資料。這三行是清除的語法。
SqlCommand commandToDelete = new SqlCommand(DeleteSpeedXmlData, conn);
commandToDelete.ExecuteNonQuery();
foreach (XmlNode RoadSpeedOneNode in RoadSpeedNodeLists)//用foreach的方式逐一取出XML中,節點的資訊
{
String speedlimit = RoadSpeedOneNode.Attributes.GetNamedItem("speedlimit").Value;
String tokm = RoadSpeedOneNode.Attributes.GetNamedItem("tokm").Value;
String fromkm = RoadSpeedOneNode.Attributes.GetNamedItem("fromkm").Value;
String roadtype = RoadSpeedOneNode.Attributes.GetNamedItem("roadtype").Value;
String endlocationpoint = RoadSpeedOneNode.Attributes.GetNamedItem("endlocationpoint").Value;
String startlocationpoint = RoadSpeedOneNode.Attributes.GetNamedItem("startlocationpoint").Value;
String locationpath = RoadSpeedOneNode.Attributes.GetNamedItem("locationpath").Value;
String roadsection = RoadSpeedOneNode.Attributes.GetNamedItem("roadsection").Value;
String sourceid = RoadSpeedOneNode.Attributes.GetNamedItem("sourceid").Value;
String routeid = RoadSpeedOneNode.Attributes.GetNamedItem("routeid").Value;
//然後insert into 剛才我們建立的那張table中 下面是insert 的語法
string SaveXmlData = "INSERT into dbo.RoadSpeedXml (speedlimit,tokm,fromkm,roadtype,endlocationpoint,startlocationpoint,locationpath,roadsection,sourceid,routeid)" + " VALUES (@speedlimit,@tokm,@fromkm,@roadtype,@endlocationpoint,@startlocationpoint,@locationpath,@roadsection,@sourceid,@routeid)";
//command.Parameters.Add("@A", A);也是insert 的語法 詳細的用法可以查一下,這個用法很過時,連compiler都會嘴你這個過時了
//但是我只會用這個,ㄏㄏ。
SqlDataAdapter da = new SqlDataAdapter(Constr, conn);
SqlCommand command = new SqlCommand(SaveXmlData, conn);
command.Parameters.Add("@speedlimit", speedlimit);
command.Parameters.Add("@tokm", tokm);
command.Parameters.Add("@fromkm", fromkm);
command.Parameters.Add("@roadtype", roadtype);
command.Parameters.Add("@endlocationpoint", endlocationpoint);
command.Parameters.Add("@startlocationpoint", startlocationpoint);
command.Parameters.Add("@locationpath", locationpath);
command.Parameters.Add("@roadsection", roadsection);
command.Parameters.Add("@sourceid", sourceid);
command.Parameters.Add("@routeid", routeid);
command.ExecuteNonQuery();
}
//路段靜態資訊http://59.120.122.53/xmlfile/roadlevel/2018/roadlevel_info_0000.xml 終點
再來是另外兩個XML的資料,雖然大致上是依樣畫葫蘆,但會用到id等PK去對應,讓他知道該怎麼匯到對映的欄位
請注意insert語法的部分 where id=id之類的地方
//抓取服務水準門檻XML http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_threshold_0000.xml 起點
foreach (XmlNode RoadSpeedOneNode in RoadSpeedNodeLists2)// 服務水準門檻
{
String colorB = RoadSpeedOneNode.Attributes.GetNamedItem("colorB").Value;
String colorG = RoadSpeedOneNode.Attributes.GetNamedItem("colorG").Value;
String colorR = RoadSpeedOneNode.Attributes.GetNamedItem("colorR").Value;
String lowvalue = RoadSpeedOneNode.Attributes.GetNamedItem("lowvalue").Value;
String topvalue = RoadSpeedOneNode.Attributes.GetNamedItem("topvalue").Value;
String index = RoadSpeedOneNode.Attributes.GetNamedItem("index").Value;
String levelname = RoadSpeedOneNode.Attributes.GetNamedItem("levelname").Value;
String level = RoadSpeedOneNode.Attributes.GetNamedItem("level").Value;
String sourceid = RoadSpeedOneNode.Attributes.GetNamedItem("sourceid").Value;
SqlDataAdapter da = new SqlDataAdapter(Constr, conn);
string SaveXmlData = "UPDATE dbo.RoadSpeedXml SET colorB = @colorB , colorG = @colorG ,colorR = @colorR ,lowvalue=@lowvalue,topvalue=@topvalue"
+ ",[index]=@index,levelname=@levelname,[level]=@level,sourceid=@sourceid where sourceid = @sourceid ";
這邊的where sourceid = @sourceid很重要,因為一開始匯入的靜態資訊已經有sourceid,所以第二段去抓取的資料就可以對說
我第二段讀到的sourceid = 第一段匯入的sourceid,這樣就可以完成比對並匯入。到正確的對硬欄位。(應喇幹)
SqlCommand command = new SqlCommand(SaveXmlData, conn);
command.Parameters.Add("@colorB", colorB);
command.Parameters.Add("@colorG", colorG);
command.Parameters.Add("@colorR", colorR);
command.Parameters.Add("@lowvalue", lowvalue);
command.Parameters.Add("@topvalue", topvalue);
command.Parameters.Add("@index", index);
command.Parameters.Add("@levelname", levelname);
command.Parameters.Add("@level", level);
command.Parameters.Add("@sourceid", sourceid);
command.ExecuteNonQuery();
}
//抓取服務水準門檻XML http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_threshold_0000.xml 終點
最後是路段動態資訊的部分,這個部分也是比較麻煩的部分,他每五分鐘就有一個新檔案 ,請自行對應上面提到的時間判別方式
//抓取路段動態資訊XML http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_value_0800.xml 起點
foreach (XmlNode RoadSpeedOneNode in RoadSpeedNodeLists3)// 路段動態資訊
{
String datacollecttime = RoadSpeedOneNode.Attributes.GetNamedItem("datacollecttime").Value;
String traveltime = RoadSpeedOneNode.Attributes.GetNamedItem("traveltime").Value;
String value = RoadSpeedOneNode.Attributes.GetNamedItem("value").Value;
String level = RoadSpeedOneNode.Attributes.GetNamedItem("level").Value;
String routeid = RoadSpeedOneNode.Attributes.GetNamedItem("routeid").Value;
String levelname = "";
int roadspeedlevel = (Convert.ToInt32(level));
switch (roadspeedlevel)
{
case 1:
levelname = "壅塞";
break;
case 2:
levelname = "車多";
break;
case 3:
levelname = "順暢";
break;
case 99:
levelname = "無資料";
break;
}
string SaveXmlData = "UPDATE dbo.RoadSpeedXml SET datacollecttime = @datacollecttime , traveltime = @traveltime ,"+
"value = @value ,level=@level,levelname = @levelname,routeid=@routeid , CheckDataTime = @GetDataUrl where routeid = @routeid ";
SqlDataAdapter da = new SqlDataAdapter(Constr, conn);
SqlCommand command = new SqlCommand(SaveXmlData, conn);
command.Parameters.Add("@datacollecttime", datacollecttime);
command.Parameters.Add("@traveltime", traveltime);
command.Parameters.Add("@value", value);
command.Parameters.Add("@level", level);
command.Parameters.Add("@levelname", levelname);
command.Parameters.Add("@routeid", routeid);
command.Parameters.Add("@GetDataUrl", GetDataUrl);
command.ExecuteNonQuery();
}
//抓取路段動態資訊XML http://59.120.122.53/xmlfile/roadlevel/20180818/roadlevel_value_0800.xml 終點
該講的都講得差不多了,基本上如果有照樣開一個TABLE的話,在執行時期開監看式,就可以看到目標網址的判別應該會長這樣
再看到SQL的table 哦對了我自己是多加了一個欄位"CheckDataTime"來確認我有沒有抓到正確的時間點啦 哈哈
希望有幫到一樣很痛苦的捧油。