C#基礎系列:Linq to Xml讀寫xml
前言:xml的操作方式有多種,但要論使用頻繁程度,博主用得最多的還是Linq to xml的方式,覺得它使用起來很方便,就用那麼幾個方法就能完成簡單xml的讀寫。之前做的一個專案有一個很變態的需求:C#專案呼叫不知道是什麼語言寫的一個WebService,然後新增服務引用總是失敗,通過代理的方式動態呼叫也總是報錯,最後沒辦法,通過傳送原始的WebRequest請求直接得到對方返回的一個xml檔案。注意過webservice的wsdl檔案的朋友應該知道這個是系統生成的xml檔案,有點複雜,研究了半天終於能正常讀寫了。今天在這裡和大家分享下。
1、介紹之前,首先回顧下Linq to xml的方式讀寫簡單xml的方法
(1)讀取xml
12345 | <?xml version="1.0"encoding="utf-8"?><BizADsList><adData aid="1"image="baidu.jpg"link="www.baidu.com"title="百度" |
123456789101112 | varstrPath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"data\test.xml");XDocument adList=XDocument.Load(strPath);varad=fromainadList.Descendants("BizADsList").Elements("adData")selectnew{image=a.Attribute("image").Value,link=a.Attribute("link").Value,title=a.Attribute("title").Value};strings="";foreach(varainad)s+=a.image; |
(2)寫xml
C#1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 | /// <summary>/// 根據得到的Document集合生成XML/// </summary>/// <param name="lstDocumentBD"></param>/// <param name="docNE"></param>/// <param name="strSpiderTime"></param>/// <param name="strNewRate"></param>privatestaticvoidSaveXmlByLstDocument(List<Document>lstDocumentBD,Document docNE,stringstrSpiderTime,stringstrNewRate){try{XDocument xDoc=newXDocument();XElement xRoot=newXElement(CSpiderConst.XML_ELE_ROOT);//1.構造Device節點XElement xDevice=newXElement(CSpiderConst.XML_ELE_DEVICE);//2.構造NE節點XElement xNE=newXElement(CSpiderConst.XML_ELE_NE);foreach(varoDocNE indocNE){XElement xItem=newXElement(CSpiderConst.XML_ELE_ITEM,newXAttribute(CSpiderConst.XML_PROP_NAME,oDocNE.Key),oDocNE.Value);xNE.Add(xItem);}//這裡增加一個<Item name='NewRate'>和<Item name='SpiderTimeEx'>節點用來儲存當前這次的利用率和當次的採集時間AddNewRateAndSpiderTime(strSpiderTime,strNewRate,xNE);xDevice.Add(xNE);//3.迴圈構造BD節點並新增到Device節點中foreach(varoDocument inlstDocumentBD){XElement xBD=newXElement(CSpiderConst.XML_ELE_BD);foreach(varoDocBD inoDocument){XElement xItem=newXElement(CSpiderConst.XML_ELE_ITEM,newXAttribute(CSpiderConst.XML_PROP_NAME,oDocBD.Key),oDocBD.Value);xBD.Add(xItem);}AddNewRateAndSpiderTime(strSpiderTime,strNewRate,xBD);xDevice.Add(xBD);}xRoot.Add(xDevice);xDoc.Add(xRoot);//4.儲存到採集器本地,以伺服器的時間和網元的AssetID來命名varstrDirectoryPath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"ReportFailed\\");if(!Directory.Exists(strDirectoryPath)){Directory.CreateDirectory(strDirectoryPath);}xDoc.Save(strDirectoryPath+docNE[TBLDeviceLCBB.PROP_ASSETID]+"_"+strSpiderTime.Replace(":","_")+".xml");}catch{CLogService.Instance.Debug("儲存XML失敗");}} |
通過XDocument、XElement物件和Element()、Elements()兩個方法能完成大部分xml檔案的操作。
2、進入今天的正題:讀寫帶名稱空間的xml檔案。
首先來看一段xml
12345678910111213141516 | <?xml version="1.0"encoding="utf-8"?><DataSet xmlns="http://WebXml.com.cn/"><xs:schema xmlns=""xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="getRegion"><msdata:aa>test</msdata:aa><xs:element name="getRegion"msdata:IsDataSet="true"msdata:UseCurrentLocale="true"><xs:element name="Province"><xs:sequence><xs:element name="RegionID"type="xs:string"minOccurs="0"/><xs:element name="RegionName"type="xs:string"minOccurs="0"/></xs:sequence></xs:element></xs:element></xs:schema></DataSet> |
第一次看到這個檔案確實讓人萌神了,比如需要取一個msdata:IsDataSet=”true”這個屬性,該怎麼取…
解析之前,先來分析下這段xml,<DataSet xmlns=”http://WebXml.com.cn/”>這段裡面有一個xmlns屬性,這個屬性是每一個標籤自帶的屬性,不信你可以新建一個xml檔案,然後在任何一個標籤裡面輸入xmlns屬性,後面都會出來很多的系統自帶的名稱空間。這個屬性表示所屬標籤在哪個名稱空間下面,所以在取的時候要帶上這個名稱空間。
先來看看解析的程式碼:
C#123456789101112 | varstrPath=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"data\test.xml");varoRoot=XDocument.Load(strPath);//取DataSet標籤varoDataSet=oRoot.Element(XName.Get("DataSet","http://WebXml.com.cn/"));//取schema標籤varoSchema=oDataSet.Element(XName.Get("schema","http://www.w3.org/2001/XMLSchema"));//取element標籤varoElement=oSchema.Element(XName.Get("element","http://www.w3.org/2001/XMLSchema"));//這兩個節點都是以xs打頭,所以名稱空間都是xs的名稱空間//取element標籤下面的IsDataSet屬性varoElementValue=oElement.Attribute(XName.Get("IsDataSet","urn:schemas-microsoft-com:xml-msdata"));//取aa標籤varoAA=oSchema.Element(XName.Get("aa","urn:schemas-microsoft-com:xml-msdata")); |
我們來解析下幾個關鍵的地方:
(1)我們來解析下
1 | <xs:schema xmlns=""xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="getRegion"> |
這一句,最前面的”xs”表示標籤所屬名稱空間的變數,xmlns:xs=”http://www.w3.org/2001/XMLSchema”這個表示xs這個名稱空間的值。所以要得到schema這個標籤需要帶上名稱空間var oSchema = oDataSet.Element(XName.Get(“schema”, “http://www.w3.org/2001/XMLSchema”));這個標籤還定義了另一個名稱空間xmlns:msdata=”urn:schemas-microsoft-com:xml-msdata”。
(2)再來看看aa標籤