LinqToXml簡介3:利用LINQ找到正確的XElement並插入資料
這篇文章,我們來講講怎麼找到之前建立的XML資料,並且對其新增新的XElement。
先確認程式碼與產出的XML資料長成下列這樣:
程式碼:
System.Xml.Linq.XNamespace oXmlNsAAA = "這完全是我亂打的一個字串";
System.Xml.Linq.XNamespace oXmlNsBBB = "http://www.foo.com/";
System.Xml.Linq.XNamespace oXmlNsCCC = "CompanyType";
System.Xml.Linq.XDocument oXml = new System.Xml.Linq.XDocument(
new System.Xml.Linq.XDeclaration("1.0", "UTF-8", "yes"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Employees",
new System.Xml.Linq.XAttribute(System.Xml.Linq.XNamespace.Xmlns + "AAA", "這完全是我亂打的一個字串"),
new System.Xml.Linq.XAttribute(System.Xml.Linq.XNamespace.Xmlns + "BBB", "http://www.foo.com/"),
new System.Xml.Linq.XAttribute(System.Xml.Linq.XNamespace.Xmlns + "CCC", "CompanyType"),
new System.Xml.Linq.XElement(oXmlNsCCC + "Company",
new System.Xml.Linq.XAttribute("Code", "Taipei"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Person",
new System.Xml.Linq.XAttribute(oXmlNsBBB + "ID", "A1234"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Name", "王小明"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Address", "台北市OOO路")
)
),
new System.Xml.Linq.XElement(oXmlNsCCC + "Company",
new System.Xml.Linq.XAttribute("Code", "Kaohsiung"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Person",
new System.Xml.Linq.XAttribute(oXmlNsBBB + "ID", "A5678"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Name", "李小華"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Address", "高雄市OOO路")
),
new System.Xml.Linq.XElement(oXmlNsAAA + "Person",
new System.Xml.Linq.XAttribute(oXmlNsBBB + "ID", "B1234"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Name", "陳小英"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Address", "高雄市XXX路")
)
)
)
);
產出之XML文件:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<AAA:Employees xmlns:AAA="這完全是我亂打的一個字串" xmlns:BBB="http://www.foo.com/" xmlns:CCC="CompanyType">
<CCC:Company Code="Taipei">
<AAA:Person BBB:ID="A1234">
<AAA:Name>王小明</AAA:Name>
<AAA:Address>台北市OOO路</AAA:Address>
</AAA:Person>
</CCC:Company>
<CCC:Company Code="Kaohsiung">
<AAA:Person BBB:ID="A5678">
<AAA:Name>李小華</AAA:Name>
<AAA:Address>高雄市OOO路</AAA:Address>
</AAA:Person>
<AAA:Person BBB:ID="B1234">
<AAA:Name>陳小英</AAA:Name>
<AAA:Address>高雄市XXX路</AAA:Address>
</AAA:Person>
</CCC:Company>
</AAA:Employees>
接著就是LINQ練習時間
挑出CCC:Company並使其成為一個IEnumerable集合。可以觀察到很有趣的結果,當失去了Employees根元素,XElement會在後續元素被自動賦予有用到命名空間的xmlns用來參考,這個設計很強。
var oCollections = oXml.Root.Elements(oXmlNsCCC + "Company");
[0]
<CCC:Company Code="Taipei" xmlns:CCC="CompanyType">
<AAA:Person BBB:ID="A1234" xmlns:BBB="http://www.foo.com/" xmlns:AAA="這完全是我亂打的一個字串">
<AAA:Name>王小明</AAA:Name>
<AAA:Address>台北市OOO路</AAA:Address>
</AAA:Person>
</CCC:Company>
[1]
<CCC:Company Code="Kaohsiung" xmlns:CCC="CompanyType">
<AAA:Person BBB:ID="A5678" xmlns:BBB="http://www.foo.com/" xmlns:AAA="這完全是我亂打的一個字串">
<AAA:Name>李小華</AAA:Name>
<AAA:Address>高雄市OOO路</AAA:Address>
</AAA:Person>
<AAA:Person BBB:ID="B1234" xmlns:BBB="http://www.foo.com/" xmlns:AAA="這完全是我亂打的一個字串">
<AAA:Name>陳小英</AAA:Name>
<AAA:Address>高雄市XXX路</AAA:Address>
</AAA:Person>
</CCC:Company>
找出在高雄公司的員工,並利用FirstOrDefault返回一個XElement。
var oKaohsiung = oXml.Root.Elements(oXmlNsCCC + "Company").Where(x => x.Attribute("Code").Value == "Kaohsiung").FirstOrDefault();
<CCC:Company Code="Kaohsiung" xmlns:CCC="CompanyType">
<AAA:Person BBB:ID="A5678" xmlns:BBB="http://www.foo.com/" xmlns:AAA="這完全是我亂打的一個字串">
<AAA:Name>李小華</AAA:Name>
<AAA:Address>高雄市OOO路</AAA:Address>
</AAA:Person>
<AAA:Person BBB:ID="B1234" xmlns:BBB="http://www.foo.com/" xmlns:AAA="這完全是我亂打的一個字串">
<AAA:Name>陳小英</AAA:Name>
<AAA:Address>高雄市XXX路</AAA:Address>
</AAA:Person>
</CCC:Company>
接續上題,找出在高雄公司的員工中編號為內含1234字串,將其姓名挑出。
var oPerson = oKaohsiung.Elements(oXmlNsAAA + "Person").Where(x => x.Attribute(oXmlNsBBB + "ID").Value.Contains("1234")).Select(x => x.Element(oXmlNsAAA + "Name").Value);
集合裡面只會有一筆資料,就是「陳小英」。
利用LINQ找出XElement目標,對其插入一筆XElement
有了上面的LINQ練習後,對於XDocument的SELECT應該是有一定的熟悉度了,在這邊我們用插入一筆XElement資料作為結束。找出台北公司的XElement,然後再子屬節點中插入一個全新的員工資料(XElement)。
oXml
.Root
.Elements(oXmlNsCCC + "Company")
.Where(x => x.Attribute("Code").Value == "Taipei")
.FirstOrDefault()
.Add(
new System.Xml.Linq.XElement(oXmlNsAAA + "Person",
new System.Xml.Linq.XAttribute(oXmlNsBBB + "ID", "C7788"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Name", "郭大頭"),
new System.Xml.Linq.XElement(oXmlNsAAA + "Address", "高雄市VVV路")
)
);
最終XML結果
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<AAA:Employees xmlns:AAA="這完全是我亂打的一個字串" xmlns:BBB="http://www.foo.com/" xmlns:CCC="CompanyType">
<CCC:Company Code="Taipei">
<AAA:Person BBB:ID="A1234">
<AAA:Name>王小明</AAA:Name>
<AAA:Address>台北市OOO路</AAA:Address>
</AAA:Person>
<AAA:Person BBB:ID="C7788">
<AAA:Name>郭大頭</AAA:Name>
<AAA:Address>高雄市VVV路</AAA:Address>
</AAA:Person>
</CCC:Company>
<CCC:Company Code="Kaohsiung">
<AAA:Person BBB:ID="A5678">
<AAA:Name>李小華</AAA:Name>
<AAA:Address>高雄市OOO路</AAA:Address>
</AAA:Person>
<AAA:Person BBB:ID="B1234">
<AAA:Name>陳小英</AAA:Name>
<AAA:Address>高雄市XXX路</AAA:Address>
</AAA:Person>
</CCC:Company>
</AAA:Employees>