· 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);
}