C# .Net MVC 組字串撈XML資料(二)

  • 651
  • 0
  • 2018-08-29

好得文西

我們說到怎麼組字串,請看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"來確認我有沒有抓到正確的時間點啦 哈哈

 

希望有幫到一樣很痛苦的捧油。