Linq to Xml
1.使用LINQ 访问XML
• 更好的操作XML
• 支持语言集成查询
• 更方便、更快速、更简单、更智能的XML API
2.LINQ to XML
• LINQ to XML 是一种启用了LINQ 的内存XML 编程接口,使用它,可以在.NET Framework 编程语言中处理XML。
• 它将XML文档置于内存中这一点很像文档对象模型(DOM) 。
• 它提供一种新的对象模型,这是一种更轻量的模型,使用也更方便,这种模型利用了Visual C# 2008 在语言方面的改进。
3.XElement 类
• 它表示一个XML 元素
• 可以使用该类
– 创建元素
– 更改元素内容 内
– 添加、更改或删除子元素
– 向元素中添加属性
– 以文本格式序列化元素内容
• 可以与System Xml中的其他类(例如 可以与System.Xml 中的其他类(例如XmlReader、XmlWriter 和XslCompiledTransform)进行互操作
4.XAttribute 类
• 属性是与元素关联的名称/值对
• XAttribute类表示XML属性 XAttribute类表示XML 属性
• 属性集合的LINQ 查询表达式与元素集合的LINQ 查询表达式看起来非常相似
5.XDocument 类
• XDocument 类包含有效的 XML 文档所需的信息。其中包括XML 声明、处理指令和注释。
• 如果需要XDocument类提供的特定功能,您只需创建XDocument对象。在很多情况下,可以直接使用Xelement。
直接使用XElement是一种比较简单的编程模型。
• XDocument 是从XContainer派生的。因此,它可以包含子节点.但是,XDocument对象只能有一个子XElement节点。
这反映了XML 标准,即在XML文档中只能有一个根元素。
6.构造XML树
• “函数构造”方法
– 通过将查询结果用作XElement 和XAttribute 对象构造函数的参数,实现了一种功能强大的
创建XML 树的方法。
– 利用这种方法,开发人员可以方便地将 XML 树从一种形状转换为另一种形状。
• 分析字符串
• 从文件加载
7.序列化XML树
•XML 树可以序列化为
– 字符串
– File
– TextWriter
– XmlWriter
– XmlReader
8.查询与转换XML树
• 基本查询
• 使用LINQ查询操作符查询
• 转换XML格式
• 将集合、数据转换成XML
• 转换成其它数据格式
9.修改XML树
• 内存中XML 树修改与函数构造
• 向XML树中添加元素、属性和节点
• 修改XML 树中的元素、属性和节点
• 从XML 树中移除元素、属性和节点
• 维护名称/值对
• 更改整个XML 树的命名空间
代码如下:
class Program { static void Main(string[] args) { //构造 XML 树 //BuildXmlTreeUsingDom(); //BuildXmlTree(); //BuildXmlTreeWithLINQ(); //BuildXmlTreeWithAttributes(); //BuildXmlDocument(); //ParseXml(); //LoadXmlFromFile(); //CatchException(); //CreateXElementUsingXmlReader(); //序列化 XML 树 //SerializeToFile1(); //SerializeToFile2(); //SerializeToXmlReader(); //查询 XML //QueryElements(); //QueryElements2(); //QueryAttributes(); //使用 LINQ 查询操作符进行查询 //LINQQuery1(); //LINQQuery2(); //LINQQuery3(); //LINQQuery4(); //LINQQuery5(); //转换 //XmlTransform1(); //XmlTransform2(); //XmlTransform3(); //修改 XML 树 //ModifyXml1(); //ModifyXml2(); //ModifyXml3(); //ModifyXml4(); } private static void SerializeToXmlReader() { string xslMarkup = @"<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'> <xsl:template match='/Parent'> <Root> <C1> <xsl:value-of select='Child1'/> </C1> <C2> <xsl:value-of select='Child2'/> </C2> </Root> </xsl:template> </xsl:stylesheet>"; XDocument xmlTree = new XDocument( new XElement("Parent", new XElement("Child1", "Child1 data"), new XElement("Child2", "Child2 data") ) ); XDocument newTree = new XDocument(); using (XmlWriter writer = newTree.CreateWriter()) { // Load the style sheet. XslCompiledTransform xslt = new XslCompiledTransform(); xslt.Load(XmlReader.Create(new StringReader(xslMarkup))); // Execute the transformation and output the results to a writer. xslt.Transform(xmlTree.CreateReader(), writer); } Console.WriteLine(newTree); } private static void SerializeToFile2() { StringBuilder sb = new StringBuilder(); XmlWriterSettings xws = new XmlWriterSettings(); xws.OmitXmlDeclaration = true; using (XmlWriter xw = XmlWriter.Create(sb, xws)) { XElement root = new XElement("Root", new XElement("Child", "child content") ); root.Save(xw); } Console.WriteLine(sb.ToString()); } private static void SerializeToFile1() { XElement root = new XElement("Root", new XElement("Child", "child content") ); root.Save("Root.xml"); string str = File.ReadAllText("Root.xml"); Console.WriteLine(str); } private static void ModifyXml4() { // Create an element with no content. XElement root = new XElement("Root"); // Add a number of name/value pairs as attributes. root.SetAttributeValue("Top", 22); root.SetAttributeValue("Left", 20); root.SetAttributeValue("Bottom", 122); root.SetAttributeValue("Right", 300); root.SetAttributeValue("DefaultColor", "Color.Red"); Console.WriteLine(root); // Replace the value of Top. root.SetAttributeValue("Top", 10); Console.WriteLine(root); // Remove DefaultColor. root.SetAttributeValue("DefaultColor", null); Console.WriteLine(root); } private static void ModifyXml3() { XElement root = XElement.Parse(@"<Root> <Child1> <GrandChild1/> <GrandChild2/> <GrandChild3/> </Child1> <Child2> <GrandChild4/> <GrandChild5/> <GrandChild6/> </Child2> <Child3> <GrandChild7/> <GrandChild8/> <GrandChild9/> </Child3> </Root>"); root.Element("Child1").Element("GrandChild1").Remove(); root.Element("Child2").Elements().ToList().Remove(); root.Element("Child3").Elements().Remove(); Console.WriteLine(root); } private static void ModifyXml2() { XElement srcTree = new XElement("Root", new XElement("Element1", 1), new XElement("Element2", 2), new XElement("Element3", 3), new XElement("Element4", 4), new XElement("Element5", 5) ); XElement xmlTree = new XElement("Root", new XElement("Child1", 1), new XElement("Child2", 2), new XElement("Child3", 3), new XElement("Child4", 4), new XElement("Child5", 5) ); xmlTree.Add(new XElement("NewChild", "new content")); xmlTree.Add( from el in srcTree.Elements() where (int)el > 3 select el ); // Even though Child9 does not exist in srcTree, the following statement will not // throw an exception, and nothing will be added to xmlTree. xmlTree.Add(srcTree.Element("Child9")); Console.WriteLine(xmlTree); } private static void ModifyXml1() { XElement root = XElement.Parse("<?xml version=\"1.0\" encoding=\"utf-8\" ?><Root Data1=\"123\" Data2=\"456\"><Child1>Content</Child1></Root>"); foreach (XAttribute att in root.Attributes()) { root.Add(new XElement(att.Name, (string)att)); } root.Attributes().Remove(); Console.WriteLine(root); } private static void XmlTransform3() { XElement custOrd = XElement.Load("CustomersOrders.xml"); IEnumerable<Customer> custList = from el in custOrd.Element("Customers").Elements("Customer") select new Customer( (string)el.Attribute("CustomerID"), (string)el.Element("CompanyName"), (string)el.Element("ContactName") ); foreach (Customer cust in custList) Console.WriteLine(cust); } private static void XmlTransform2() { XElement co = XElement.Load("CustomersOrders.xml"); XElement newCustOrd = new XElement("Root", from cust in co.Element("Customers").Elements("Customer") select new XElement("Customer", cust.Attributes(), cust.Elements(), new XElement("Orders", from ord in co.Element("Orders").Elements("Order") where (string)ord.Element("CustomerID") == (string)cust.Attribute("CustomerID") select new XElement("Order", ord.Attributes(), ord.Element("EmployeeID"), ord.Element("OrderDate"), ord.Element("RequiredDate"), ord.Element("ShipInfo") ) ) ) ); Console.WriteLine(newCustOrd); } private static void XmlTransform1() { Dictionary<string, string> dict = new Dictionary<string, string>(); dict.Add("Child1", "Value1"); dict.Add("Child2", "Value2"); dict.Add("Child3", "Value3"); dict.Add("Child4", "Value4"); XElement root = new XElement("Root", from keyValue in dict select new XElement(keyValue.Key, keyValue.Value) ); Console.WriteLine(root); } private static void LINQQuery5() { XElement root = XElement.Load("Data.xml"); IEnumerable<decimal> extensions = from el in root.Elements("Data") let extension = (decimal)el.Element("Quantity") * (decimal)el.Element("Price") where extension >= 25 orderby extension select extension; foreach (decimal ex in extensions) Console.WriteLine(ex); } private static void LINQQuery4() { XElement root = XElement.Load("Data.xml"); IEnumerable<decimal> prices = from el in root.Elements("Data") let price = (decimal)el.Element("Price") orderby price select price; foreach (decimal el in prices) Console.WriteLine(el); } private static void LINQQuery3() { XElement root = XElement.Parse(@"<Root> <Child1> <GrandChild1>GC1 Value</GrandChild1> </Child1> <Child2> <GrandChild2>GC2 Value</GrandChild2> </Child2> <Child3> <GrandChild3>GC3 Value</GrandChild3> </Child3> <Child4> <GrandChild4>GC4 Value</GrandChild4> </Child4> </Root>"); string grandChild3 = (string) (from el in root.Descendants("GrandChild3") select el).First(); Console.WriteLine(grandChild3); } private static void LINQQuery2() { XElement root = XElement.Parse(@"<root> <para> <r> <t>Some text </t> </r> <n> <r> <t>that is broken up into </t> </r> </n> <n> <r> <t>multiple segments.</t> </r> </n> </para> </root>"); IEnumerable<string> textSegs = from seg in root.Descendants("t") select (string)seg; string str = textSegs.Aggregate(new StringBuilder(), (sb, i) => sb.Append(i), sp => sp.ToString() ); Console.WriteLine(str); } private static void LINQQuery1() { XElement root = XElement.Load("PurchaseOrder.xml"); IEnumerable<XElement> address = from el in root.Elements("Address") where (string)el.Attribute("Type") == "Billing" select el; foreach (XElement el in address) Console.WriteLine(el); } private static void QueryAttributes() { XElement val = new XElement("Value", new XAttribute("ID", "1243"), new XAttribute("Type", "int"), new XAttribute("ConvertableTo", "double"), "100"); IEnumerable<XAttribute> listOfAttributes = from att in val.Attributes() select att; foreach (XAttribute a in listOfAttributes) Console.WriteLine(a); } private static void QueryElements2() { XElement purchaseOrders = XElement.Load("PurchaseOrders.xml"); IEnumerable<XElement> names = from el in purchaseOrders .Elements("PurchaseOrder") .Elements("Address") .Elements("Name") select el; foreach (XElement e in names) Console.WriteLine(e); } private static void QueryElements() { XElement po = XElement.Load("PurchaseOrder.xml"); IEnumerable<XElement> childElements = from el in po.Elements() select el; foreach (XElement el in childElements) Console.WriteLine("Name: " + el.Name); } private static void CreateXElementUsingXmlReader() { XmlReader r = XmlReader.Create("books.xml"); while (r.NodeType != XmlNodeType.Element) r.Read(); XElement e = XElement.Load(r); Console.WriteLine(e); } private static void CatchException() { try { XElement contacts = XElement.Parse( @"<Contacts> <Contact> <Name>Jim Wilson</Name> </Contact> </Contcts>"); Console.WriteLine(contacts); } catch (System.Xml.XmlException e) { Console.WriteLine(e.Message); } } private static void LoadXmlFromFile() { XElement booksFromFile = XElement.Load(@"books.xml"); Console.WriteLine(booksFromFile); } private static void ParseXml() { XElement contacts = XElement.Parse( @"<Contacts> <Contact> <Name>Patrick Hines</Name> <Phone Type=""home"">206-555-0144</Phone> <Phone type=""work"">425-555-0145</Phone> <Address> <Street1>123 Main St</Street1> <City>Mercer Island</City> <State>WA</State> <Postal>68042</Postal> </Address> <NetWorth>10</NetWorth> </Contact> <Contact> <Name>Gretchen Rivas</Name> <Phone Type=""mobile"">206-555-0163</Phone> <Address> <Street1>123 Main St</Street1> <City>Mercer Island</City> <State>WA</State> <Postal>68042</Postal> </Address> <NetWorth>11</NetWorth> </Contact> </Contacts>"); Console.WriteLine(contacts); } private static void BuildXmlDocument() { XDocument d = new XDocument( new XComment("This is a comment."), new XProcessingInstruction("xml-stylesheet", "href='mystyle.css' title='Compact' type='text/css'"), new XElement("Pubs", new XElement("Book", new XElement("Title", "Artifacts of Roman Civilization"), new XElement("Author", "Moreno, Jordao") ), new XElement("Book", new XElement("Title", "Midieval Tools and Implements"), new XElement("Author", "Gazit, Inbar") ) ), new XComment("This is another comment.") ); d.Declaration = new XDeclaration("1.0", "utf-8", "true"); Console.WriteLine(d); d.Save("test.xml"); } private static void BuildXmlTreeWithAttributes() { XElement c = new XElement("Customers", new XElement("Customer", new XElement("Name", "John Doe"), new XElement("PhoneNumbers", new XElement("Phone", new XAttribute("type", "home"), "555-555-5555"), new XElement("Phone", new XAttribute("type", "work"), "666-666-6666") ) ) ); Console.WriteLine(c); } private static void BuildXmlTreeWithLINQ() { XElement srcTree = new XElement("Root", new XElement("Element", 1), new XElement("Element", 2), new XElement("Element", 3), new XElement("Element", 4), new XElement("Element", 5) ); XElement xmlTree = new XElement("Root", new XElement("Child", 1), new XElement("Child", 2), from el in srcTree.Elements() where (int)el > 2 select el ); Console.WriteLine(xmlTree); } private static void BuildXmlTree() { XElement contacts = new XElement("Contacts", new XElement("Contact", new XElement("Name", "Patrick Hines"), new XElement("Phone", "206-555-0144"), new XElement("Address", new XElement("Street1", "123 Main St"), new XElement("City", "Mercer Island"), new XElement("State", "WA"), new XElement("Postal", "68042") ) ) ); Console.WriteLine(contacts); } private static void BuildXmlTreeUsingDom() { XmlDocument doc = new XmlDocument(); XmlElement name = doc.CreateElement("Name"); name.InnerText = "Patrick Hines"; XmlElement phone1 = doc.CreateElement("Phone"); phone1.SetAttribute("Type", "Home"); phone1.InnerText = "206-555-0144"; XmlElement phone2 = doc.CreateElement("Phone"); phone2.SetAttribute("Type", "Work"); phone2.InnerText = "425-555-0145"; XmlElement street1 = doc.CreateElement("Street1"); street1.InnerText = "123 Main St"; XmlElement city = doc.CreateElement("City"); city.InnerText = "Mercer Island"; XmlElement state = doc.CreateElement("State"); state.InnerText = "WA"; XmlElement postal = doc.CreateElement("Postal"); postal.InnerText = "68042"; XmlElement address = doc.CreateElement("Address"); address.AppendChild(street1); address.AppendChild(city); address.AppendChild(state); address.AppendChild(postal); XmlElement contact = doc.CreateElement("Contact"); contact.AppendChild(name); contact.AppendChild(phone1); contact.AppendChild(phone2); contact.AppendChild(address); XmlElement contacts = doc.CreateElement("Contacts"); contacts.AppendChild(contact); doc.AppendChild(contacts); Console.WriteLine(doc.OuterXml); } }
10.生成rss
public class RSSHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { NorthwindDataContext db = new NorthwindDataContext(); XElement rssRoot = new XElement("rss", new XAttribute("version", "2.0"), new XElement("channel", new XElement("title", "My RSS Feed"), new XElement("link", "http://www.cnblogs.com/refactor"), new XElement("description", "Northwind Products Feed"), from product in db.Product orderby product.Name descending select new XElement("item", new XElement("title", product.Name), new XElement("link", "p.aspx?id=" + product.ProductID), new XElement("description", "Color: " + product.Color+"<br/>Size:"+product.Size) ) ) ); context.Response.Write(rssRoot.ToString()); } public bool IsReusable { get { return false; } } }
效果图: