· XML数据格式
· 我们可以使用XMLDocument类在文档对象模型(DOM)层次结构内导航
· 也可以使用XMLReader和XMLWriter。使用XML更复杂,但可以读取更大的文件。使用XMLDocument把文档全部加载进了内存中,使用XMLReader可以逐个节点读取。
· 另一个使用XML的方式是System.Xml.Serialization,把.NET对象序列化为XML,也可以把XML反序列化为.NET对象。
· 查询XML内容时,可以使用XML标准XPath或Linq to Xml。
· 对于WCF,XML可以压缩为二进制格式。JSON也可以压缩为二进制格式(BSON) .
· 我们可以使用WSDL描述XML数据,使用Swagger描述JSON数据。
· XmlReader,XMLDocument和XPathNavigator类
· XmlReader和XmlWriter类提供了读写大型XML文档的快速方式。
· 常见的遍历文档的方法有Read()方法进入下一个节点。然后验证该节点是否有值(HasValue()),或者该节点是否有特性(HasAttributes()),XmlReader还可以读取强类型的数据,它有几个方法如:ReadElementContentAsDouble(),ReadElementContentAsString()
读取文本内容:
using (XmlReader reader = XmlReader.Create("books.xml")) { while(reader.Read()) { if (reader.NodeType == XmlNodeType.Text) { Console.WriteLine(reader.Value); } } }读取节点信息:
using (XmlReader reader = XmlReader.Create(bookFile)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { for (int i = 0; i < reader.AttributeCount; i++) { Console.WriteLine(reader.GetAttribute(i)); } } } }写入XmlWriter写入一个流:
var setting = new XmlWriterSettings() { Indent = true,//缩进 IndentChars = " ",//缩进字符 NewLineOnAttributes = false, Encoding = Encoding.UTF8, WriteEndDocumentOnClose = true, }; StreamWriter stream = File.CreateText(newXml);//打开一个写入流 using (XmlWriter writer = XmlWriter.Create(stream, setting)) { writer.WriteStartDocument(); writer.WriteStartElement("book"); writer.WriteAttributeString("gener", "Mystery"); writer.WriteAttributeString("publicationdate", "2001"); writer.WriteAttributeString("ISBN", "123456789"); writer.WriteElementString("title", "Case of missing Cookie"); writer.WriteStartElement("author"); writer.WriteElementString("name", "Cookie Monster"); writer.WriteEndElement(); writer.WriteElementString("price", "9.99"); writer.WriteEndElement(); writer.WriteEndDocument(); }
· XmlDocument类用于在.NET中读写DOM类。与XmlReader和XmlWriter不同的是XmlDocument具有读写的功能,并可以随机访问DOM树。常见的遍历方法有GetElementByTagName()获取指定元素的列表,然后调用子集的OuterXml,InnerXml,NextSibling,PreviousSibling等属性。
遍历层次结构:
using (FileStream stream = File.OpenRead(bookFile)) { var doc = new XmlDocument(); doc.Load(stream); var nodeList = doc.GetElementsByTagName("author"); foreach (XmlNode item in nodeList) { //OuterXml包含此节点及子节点 Console.WriteLine($"OuterXml:{item.OuterXml}"); //InnerXml包含子节点 Console.WriteLine($"InnerXml:{item.InnerXml}"); Console.WriteLine($"兄弟节点(下一个节点)的OuterXml:{item.NextSibling.OuterXml}"); Console.WriteLine($"兄弟节点(上一个节点)的OuterXml:{item.PreviousSibling.OuterXml}"); Console.WriteLine($"父节点的OuterXml:{item.ParentNode.OuterXml}"); break; } Console.Read(); }XMLDocument写入文件:
var doc = new XmlDocument(); using (FileStream stream = File.OpenRead(bookFile)) { doc.Load(stream); } var book = doc.CreateElement("book"); book.SetAttribute("genre", "MyStery"); book.SetAttribute("publicationdate", "2001"); book.SetAttribute("ISBN", "123456789"); var title = doc.CreateElement("title"); title.InnerText = "Case of Missing Cookie"; book.AppendChild(title);//将title节点添加到book子节点的末尾 var author = doc.CreateElement("author"); book.AppendChild(author);//将author节点添加到book子节点的末尾 var name = doc.CreateElement("name"); name.InnerText = "Cookie Monster"; author.AppendChild(name); var price = doc.CreateElement("price"); price.InnerText = "9.99"; book.AppendChild(price); doc.DocumentElement.AppendChild(book);//将book节点添加到根节点(bookStore)的子节点的末尾 var setting = new XmlWriterSettings() { Indent = true, IndentChars = "\t", NewLineChars = Environment.NewLine, }; using (StreamWriter stream = File.CreateText(newbook2)) { //创建或打开一个写入流 using (XmlWriter writer = XmlWriter.Create(stream, setting)) { //创建一个写入器,并将所有内容写入进去 doc.WriteContentTo(writer); } var list = doc.GetElementsByTagName("title"); foreach (XmlNode item in list) { Console.WriteLine(item.OuterXml); } Console.Read(); }
· XPathNavigator也可以读写XML文档,特点是可以通过XPath语句访问到指定元素。要注意的是,只用通过XMLDocument创建的对象才可以修改文件,通过XMLPathDocument创建的对象是只读的。。
XPathNavigator读取元素:
var doc = new XPathDocument(bookFile); var xPathNavigator = doc.CreateNavigator(); //选择和设置一组重复节点 var iter = xPathNavigator.Select("/bookstore/book[@genre='novel']"); while(iter.MoveNext()) { var newiter = iter.Current.SelectDescendants(XPathNodeType.Element, false); while(newiter.MoveNext()) { Console.WriteLine($"{newiter.Current.Name} {newiter.Current.Value}"); } }XPathNavigator修改元素:
//注意:只有XmlDocument才能修改XML元素! XmlDocument doc = new XmlDocument(); doc.Load(bookFile); XPathNavigator xPathNavigator = doc.CreateNavigator(); //选择和设置一组重复节点 var iter = xPathNavigator.Select("/bookstore/book[@genre='novel']"); while (iter.MoveNext()) { var iter_items = iter.Current.SelectDescendants(XPathNodeType.Element, false); while (iter_items.MoveNext()) { var value = iter_items.Current.Value; iter_items.Current.SetValue("100"); } } doc.Save("book2.xml");
· XML序列化
· .NET Framework为序列化提供了两个名称空间:System.Xml.Serialization和System.Xml.XmlSerializer。它包含的类可用于把对象序列化为Xml文档或者流。这也就表示把对象的公共属性和字段转换为Xml元素或属性。
· 我们可以在POCO的属性上添加XmlElement元素,来定义输出XML的名称,命名空间,类型等。如:ElementName设置XML元素的名称,Namespace设置命名空间的名称,Order设置顺序
· XmlAttribute可以将POCO的属性设置为XML的属性,并且可以设置XML属性的名称,命名空间等。
序列化一个对象:
Product product = new Product() { CategoryID = 1, Discontinued = true, Discount = 15, ProductID = 1, ProductName = "戴尔笔记本电脑", QuantityPerUnit = "6", ReorderLevel = 1, SupplierID = 1, UnitPrice = 4000, UnitsInStock = 10, UnitsOnOrder = 0 }; //打开一个文件流 var stream = File.OpenWrite("product.xml"); //向文件流中写入字符 using (TextWriter writer = new StreamWriter(stream)) { //创建一个序列化实例对象 XmlSerializer serializer = new XmlSerializer(typeof(Product)); serializer.Serialize(writer, product);//将对象写入到文件流中 } Console.Read();反序列化一个对象:
Product product; //打开一个文件流 using (var stream = new FileStream("product.xml", FileMode.Open)) { var serializer = new XmlSerializer(typeof(Product)); product = (Product)serializer.Deserialize(stream); }