關于XML,學校那會,老師在口中僅僅提及,自己也未曾深入接觸過,僅是些將最基本XML文件內容顯示在web定義的表格中之類的簡單操作,如今項目中的收發電文涉及到復雜XML的操作。趁此契機好好回顧下XML知識。
XML作為一種可擴展的標記語言,可以一種簡單文本格式存儲數據的方式,被任何計算機讀取。非常靈活。標準的XML格式(分層組織)是包含一個版本信息的節點(第一行),和一個可包含多級層級節點的根結點。和HTML不同的是,XML的節點名稱、節點屬性等可自定義,并區別大小寫,這點反映了其靈活性。
關于XML節點的內容,包含命名空間(前綴)、屬性。至于命名空間是個啥,其實也很好理解,如兩軍開戰,兵卒廝殺,為了識別己方人員,不同的衣服、裝飾這些都是所謂的馬甲。命名空間也是同樣的道理。穿上馬甲,表明自己身份,是誰手下的兵,該歸誰管。
完整的Soap格式的XML就我目前遇到的分為兩種:
1. 帶層級的包含命名空間,就是x0里面包含的X1,x2Body里面包含x3、x4 ,而不是單層存在
<?xml version="1.0" encoding="UTF-8"?> <x0:Envelope xmlns:x0="http://www.w3school.com.cn/Envelope" xmlns:x1="http://www.w3school.com.cn/Header"> <x1:Header> <x1:Type>ICC</x1:Type> <x1:Version>01</x1:Version> </x1:Header> <x2:Body xmlns:x2="http://www.w3school.com.cn/Body" xmlns:x3="http://www.w3school.com.cn/IBBC/01" xmlns:x4="http://www.w3school.com.cn/ICCB/01"> <x3:SecondInform> <x4:Status> <x4:StatusCode>0000</x4:StatusCode> </x4:Status> </x3:SecondInform> </x2:Body> </x0:Envelope>
對于這種方式寫操作,思路是: 一層一層進行,然后進行拼接,命名空間尤其是帶前綴的,用 XElement 來處理,引用的具體來源,用 XAttribute 來表示,此外對于標簽數據的寫入,同樣也是用XElement元素,格式是:XElement(命名空間,"標簽名","標簽值"),對于子節點的話,就是嵌套,在第三個參數標簽值的位置上,再New Element元素即可
public void CreateXML() { //寫入命名空間 XNamespace x0 = @"http://www.w3school.com.cn/Envelope"; XNamespace x1 = @"http://www.w3school.com.cn/Header"; XNamespace x2 = @"http://www.w3school.com.cn/Body"; XNamespace x3 = @"http://www.w3school.com.cn/IBBC/01"; XNamespace x4 = @"http://www.w3school.com.cn/ICCB/01"; //創建根元素 XElement root = new XElement(x0+"Envelop",new XAttribute(XNamespace.Xmlns+"x0",x0.NamespaceName), new XAttribute(XNamespace.Xmlns+"x1",x1.NamespaceName), new XElement(x1+"Header", new XElement(x1+"Type","ICC"), new XElement(x1+"Version","01")) , new XElement(x2+"Body",new XAttribute(XNamespace.Xmlns+"x2",x2.NamespaceName), new XAttribute(XNamespace.Xmlns+"x3",x3.NamespaceName), new XAttribute(XNamespace.Xmlns+"x4",x4.NamespaceName), new XElement(x3 + "SecondInform", new XElement(x4 + "Status", new XElement(x4 + "StatusCode","0000")))) ); Console.WriteLine(root); }
2. 對于純單層級的命名空間,就是x0標簽中只有x0,x1則在其下一個標簽
<?xml version="1.0" encoding="utf-8"?> <x0:Envelop xmlns:x0="http://www.w3school.com.cn/Envelope"> <x1:Header xmlns:x1="http://www.w3school.com.cn/Header"> <x1:Header> <x1:Type>ICC</x1:Type> <x1:Version>01</x1:Version> </x1:Header> </x1:Header> <x1:Body xmlns:x1="http://www.w3school.com.cn/Body"> <x2:IBBC xmlns:x2="http://www.w3school.com.cn/IBBC/01"> <x2:SecondInform>123</x2:SecondInform> <x2:Status> <x2:StatusCode>0000</x2:StatusCode> </x2:Status> </x2:IBBC> </x1:Body> </x0:Envelop>
如果要創建這種格式的XML,總的來說和第一種的思路是完全一樣,我理解的不同就是,層級關系改變了,所以在寫操作的時候,部分代碼需要對應的調整,只要掌握了思想,不管嵌套多少層,一層一層的進行寫入,進行調試,就不會出錯,如下
public void CreateXML() { //寫入命名空間 XNamespace x0 = @"http://www.w3school.com.cn/Envelope"; XNamespace x1h = @"http://www.w3school.com.cn/Header"; XNamespace x1b = @"http://www.w3school.com.cn/Body"; XNamespace x2 = @"http://www.w3school.com.cn/IBBC/01"; //創建根元素 XElement root = new XElement(x0+"Envelop",new XAttribute(XNamespace.Xmlns+"x0",x0.NamespaceName), new XElement(x1h+"Header",new XAttribute(XNamespace.Xmlns+"x1",x1h.NamespaceName), new XElement(x1h+"Header", new XElement(x1h+"Type","ICC"), new XElement(x1h+"Version","01")) ), new XElement(x1b+"Body",new XAttribute(XNamespace.Xmlns+"x1",x1b.NamespaceName), new XElement(x2+"IBBC",new XAttribute(XNamespace.Xmlns+"x2",x2.NamespaceName), new XElement(x2+"SecondInform","123"), new XElement(x2 + "Status", new XElement(x2+"StatusCode","0000")) ) ) ); Console.WriteLine(root); }
很多時候要求的是動態的XML,比如在某個指定節點下循環插入某個數據源(數據庫)中的數據,對于此類,需要兩步走,第一,獲取指定位置的節點,第二在該位置下插入數據,至于循環的話,FOR語句即可處理,如下
//獲取插入點元素 XElement LocNode = root.Descendants(x2 + "StatusCode").FirstOrDefault(); //需要循環創建的xml節點 for (int i = 0; i < dt.Rows.Count; i++) { XElement Transnode = new XElement(x2 + "CollRec", new XElement(x2 + "NewNode", dt.Rows[i][0]), new XElement(x2 + "TwoNode", new XElement(x2 + "Test1", dt.Rows[i][1]), new XElement(x2 + "Test2", dt.Rows[i][2])) ); //在指定節點下插入新元素 LocNode.AddAfterSelf(Transnode); }
如此便已成功創建完復雜電文格式的XML。后面的話我會陸續介紹關于復雜XML操作的更多說明,包括解析、簡單操作、以及其他復雜類型的XML。
--舊時王謝堂前燕,飛入尋常百姓家
--市人皆大笑,舉手揶揄之
文章列表