c#操作Xml(四)
上集回顧
??? 上集初步介紹了Linq to Xml的基本操作,簡單的新建xml操作和簡單的查詢xml操作。不過,可以注意到的是上集里面的xml都是沒有Namespace的xml,那么有Namespace的xml如何操作哪?
設置目標
??? 先看看我們目標,完整這樣一個xml:
<?xml version="1.0" encoding="utf-8" ?> <v:persons xmlns:v="http://www.cnblogs.com/vwxyzh/"><v:person><v:firstName>Zhenway</v:firstName><v:lastName>Yan</v:lastName><v:address>http://www.cnblogs.com/vwxyzh/</v:address></v:person> </v:persons>??? 注意,這個xml的每一個節點都是 http://www.cnblogs.com/vwxyzh/ 這個命名空間下的。
??? 當然,這樣的xml也有很多種等效寫法,具體請參考w3shools。
分析實現手段
??? 與之前一集相比,這里的”persons”,不再是一個純粹的”persons”,而是一個帶有Namespace的persons,所以在創建這樣一個節點時不再是之前的:
var persons = new XElement("persons");??? 而是需要修改成帶有Namespace的節點名。
??? 那么如何獲得這個帶有Namespace的節點名哪?
??? 好吧,讓我們回過頭來看看XElement的構造函數:
public XElement(XName name);??? 注意哦,參數的類型是XName,而不是string,那么平時為什么能用string哪?因為上一集里面提到過,XName定義了一個隱式的轉換,可以把string隱式的轉換成XName。
??? 所以,關于Namespace自然也要從XNamespace入手,然后找一個能夠變成XName的方法,察看XNamespace的定義,就可以看到:
public static XName operator +(XNamespace ns, string localName);??? 只要把XNamespace加上本地名稱(string),就是一個XName了,非常簡單。
??? 再看看如何創建一個XNamespace:
public static implicit operator XNamespace(string namespaceName);??? 又是隱式轉換。。。來看看具體如何創建一個帶namespace的persons吧:
XNamespace v = "http://www.cnblogs.com/vwxyzh/"; var persons = new XElement(v + "persons");??? 定義一個namespace,在使用時直接+string即可。在c#里面這已經是最簡單的方式了。
實現
??? 到這里,已經可以完成上面的那個目標xml了:
XNamespace v = "http://www.cnblogs.com/vwxyzh/"; XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", null),new XElement(v + "persons",new XElement(v + "person",new XElement(v + "firstName", "Zhenway"),new XElement(v + "lastName", "Yan"),new XElement(v + "address", "http://www.cnblogs.com/vwxyzh/")))); doc.Save(Console.Out);??? 來看看執行結果:
<?xml version="1.0" encoding="gb2312"?> <persons xmlns="http://www.cnblogs.com/vwxyzh/"><person><firstName>Zhenway</firstName><lastName>Yan</lastName><address>http://www.cnblogs.com/vwxyzh/</address></person> </persons>??? 和預期的略有不同,首先encoding被修改成gb2312,這是因為中文操作系統的Console的編碼是gb2312,所以Xml的encoding被自動修改了,其次,原來的Namespace用v來縮寫,但是輸出的xml缺是改用了默認Namespace,不過如果看過前面提到的w3schools的話,就知道這兩者是等價xml。
擴展
??? 在查找一個xml時,同樣也是需要一個XName,因此當遇到有Namespace的xml,也可以用同樣的手法:
XDocument doc = XDocument.Parse(@"<?xml version=""1.0"" encoding=""utf-8"" ?> <v:persons xmlns:v=""http://www.cnblogs.com/vwxyzh/""><v:person><v:firstName>Zhenway</v:firstName><v:lastName>Yan</v:lastName><v:address>http://www.cnblogs.com/vwxyzh/</v:address></v:person><v:person><v:firstName>Allen</v:firstName><v:lastName>Lee</v:lastName><v:address>http://www.cnblogs.com/allenlooplee/</v:address></v:person> </v:persons>");XNamespace v = "http://www.cnblogs.com/vwxyzh/";foreach (var item in from person in doc.Root.Descendants(v + "person")where (string)person.Element(v + "firstName") == "Zhenway"select (string)person.Element(v + "address")){Console.WriteLine(item);}?
總結和下集預告
??? Linq to Xml的介紹基本上就告一段落,不過,無論是Dom Api還是Linq to Xml都是In-Memory的工作方式,這樣的工作方式對內存的要求相對較高,而且不適合超大xml文件的處理。
??? 因此,下集將介紹如何不占用內存的寫一個超大的xml,當然其中也有Linq to Xml的一部分內容(Linq to Xml當初就預留了這部分)。
總結
以上是生活随笔為你收集整理的c#操作Xml(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载】2010年最全最新令人无语语录
- 下一篇: 关于C#的Main(String[] a