一,读写流格式的xml
1。xmlReader类读取xml
xmlReader是一个抽象类,所以不能直接实例化。而要调用工厂方法Create,返回派生自xmlreader新类的一个实例。在创建读取器时。节点可以使用Read方法读取。只要没有节点可用,Read方法就返回false。
xml实例:
<?xml version='1.0'?> <!-- This file represents a fragment of a book store inventory database --> <bookstore> <book genre="autobiography" publicationdate="1991" ISBN="1-861003-11-0"> <title>The Autobiography of Benjamin Franklin</title> <author> <first-name>Benjamin</first-name> <last-name>Franklin</last-name> </author> <price>8.99</price> </book> <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2"> <title>The Confidence Man</title> <author> <first-name>Herman</first-name> <last-name>Melville</last-name> </author> <price>11.99</price> </book> <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6"> <title>The Gorgias</title> <author> <name>Plato</name> </author> <price>9.99</price> </book> </bookstore>
代码实例:
static void ReadTextNode2() { using (XmlReader reader = XmlReader.Create(BooksFileName)) { //第一种按照reader.EOF循环 //while (!reader.EOF) { //.etc //reader.Read(); //} //第二种直接reader.Read() while (reader.Read()) { //只有xmlnodetype.text类型的节点值才写入控制台 if (reader.NodeType == XmlNodeType.Text) { WriteLine($"{reader.Value}"); } //读取节点内容 if (reader.MoveToContent() == XmlNodeType.Element) { if (reader.Name == "price") { decimal price = reader.ReadElementContentAsDecimal(); price += price * .25m; WriteLine($"{price}"); } else if (reader.Name == "title") { WriteLine($"{reader.ReadElementContentAsString()}"); } //循环遍历获取属性,如果有特性,HasAttribute会返回true for (int i = 0; i < reader.AttributeCount; i++) { WriteLine($"{reader.GetAttribute(i)}"); } //movetocontent()方法查找的第一个元素是<bookstore>,因为他是一个元素所以通过了if语句中的检查。但是不包含简单文本类型,会导致ReadElementContentAsString方法报错 try { WriteLine($"{reader.ReadElementContentAsString()}"); } catch (Exception ex) { continue; } } } } }
2.xmlwrite 写入xml文件
xml实例:
<?xml version="1.0" encoding="utf-8"?> <book genre="Mystery" publicationdate="2001" ISBN="123456789"> <title>Case of the Missing Cookie</title> <author> <name>Cookie Monster</name> </author> <price>9.99</price> </book>
代码实例:
public static void WriterSample() { var settings = new XmlWriterSettings { Indent = true, NewLineOnAttributes = true, Encoding = Encoding.UTF8, WriteEndDocumentOnClose = true }; StreamWriter stream = File.CreateText(NewBooksFileName); using (XmlWriter writer = XmlWriter.Create(stream, settings)) { writer.WriteStartDocument(); //Start creating elements and attributes writer.WriteStartElement("book"); writer.WriteAttributeString("genre", "Mystery"); writer.WriteAttributeString("publicationdate", "2001"); writer.WriteAttributeString("ISBN", "123456789"); writer.WriteElementString("title", "Case of the Missing Cookie"); writer.WriteStartElement("author"); writer.WriteElementString("name", "Cookie Monster"); writer.WriteEndElement(); writer.WriteElementString("price", "9.99"); writer.WriteEndElement(); writer.WriteEndDocument(); } }
注:1.XmlReader.MoveToContent Method
返回
此方法找到的当前节点的 NodeType;如果读取器已到达输入流的末尾,则为 XmlNodeType.None
。
2.Value ReadString ReadContentString ReadElementContentAsString 的区别
XmlReader 中关于读取值的方法、属性极其的多,这里以读 String 为例介绍其区别。
从上上级节点 | 从上级节点 | 从文本节点 | “指针”移动情况 | |
Value | 获取不到 | 获取不到 | 成功 | 不移动 |
ReadString() | 出错 | 成功 | 成功 | 当前节点结束节点 |
ReadContentAsString() | 出错 | 出错 | 成功 | 当前节点结束节点 |
ReadElementContentAsString() | 出错 | 成功 | 出错 | 当前节点下一个兄弟节点 |
- 从上上级节点:从 Text 或 CDATA 的上级节点的上级节点读取
- 从上级节点:从 Text 或 CDATA 的上级节点读取
- 从文本节点:从 Text 或 CDATA 读取
- “指针”移动情况:读取完成后移动到下一节点的情况
举例解释
有 XML 片段:
<n1><n1.1>content1</n1.1><n1.2>content2</n1.2></n1>
若当前指针是 n1:
- Value 零长度字符串
- ReadString() 出错
- ReadContentAsString() 出错
- ReadElementContentAsString() 出错
若当前指针是 n1.1:
- Value 零长度字符串
- ReadString() content1
- ReadContentAsString() 出错
- ReadElementContentAsString() content1
若当前指针是 content1:
- Value content1
- ReadString() content1
- ReadContentAsString() content1
- ReadElementContentAsString() 出错
“指针”移动情况:
- Value 不变
- ReadString() </n1.1>
- ReadContentAsString() </n1.1>
- ReadElementContentAsString() <n1.2>
二,xmldocument读写文档
1.xmldocument读取xml
public static void NavigateXml() { using (FileStream stream = File.OpenRead(BooksFileName)) { var doc = new XmlDocument(); doc.Load(stream); XmlNodeList nodelist = doc.GetElementsByTagName("author"); foreach (XmlNode node in nodelist) { WriteLine($"outer xml:{node.OuterXml}"); WriteLine($"inner xml:{node.InnerXml}"); WriteLine($"next sibling outer xml:{node.NextSibling.OuterXml}"); WriteLine($"next sibling inner xml:{node.NextSibling.InnerXml}"); WriteLine($"previous sibling outer xml:{node.PreviousSibling.OuterXml}"); WriteLine($"FIrst Child outer xml:{node.FirstChild.OuterXml}"); WriteLine($"parent name:{node.ParentNode.Name}"); } } }
2.xmldocument 写入xml
public static void CreateXml() { var doc = new XmlDocument(); using (FileStream stream = File.OpenRead("books.xml")) { doc.Load(stream); } //create a new 'book' element XmlElement newBook = doc.CreateElement("book"); //set some attributes newBook.SetAttribute("genre", "Mystery"); newBook.SetAttribute("publicationdate", "2001"); newBook.SetAttribute("ISBN", "123456789"); //create a new 'title' element XmlElement newTitle = doc.CreateElement("title"); newTitle.InnerText = "Case of the Missing Cookie"; newBook.AppendChild(newTitle); //create new author element XmlElement newAuthor = doc.CreateElement("author"); newBook.AppendChild(newAuthor); //create new name element XmlElement newName = doc.CreateElement("name"); newName.InnerText = "Cookie Monster"; newAuthor.AppendChild(newName); //create new price element XmlElement newPrice = doc.CreateElement("price"); newPrice.InnerText = "9.95"; newBook.AppendChild(newPrice); //add to the current document doc.DocumentElement.AppendChild(newBook); var settings = new XmlWriterSettings { Indent = true, IndentChars = "\t", NewLineChars = Environment.NewLine }; //write out the doc to disk using (StreamWriter streamWriter = File.CreateText(NewBooksFileName)) using (XmlWriter writer = XmlWriter.Create(streamWriter, settings)) { doc.WriteContentTo(writer); } XmlNodeList nodeLst = doc.GetElementsByTagName("title"); foreach (XmlNode node in nodeLst) { WriteLine(node.OuterXml); } }
三,在xml中序列化对象
product类:
using System; using System.Collections.Generic; using System.Text; namespace ObjectToXmlSerializationSample { // 注意: 生成的代码可能至少需要 .NET Framework 4.5 或 .NET Core/Standard 2.0。 /// <remarks/> [System.SerializableAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] public partial class Product { private byte productIDField; private string productNameField; private byte supplierIDField; private byte categoryIDField; private byte quantityPerUnitField; private ushort unitPriceField; private byte unitsInStockField; private byte unitsOnOrderField; private byte reorderLevelField; private bool discontinuedField; private byte discountField; /// <remarks/> public byte ProductID { get { return this.productIDField; } set { this.productIDField = value; } } /// <remarks/> public string ProductName { get { return this.productNameField; } set { this.productNameField = value; } } /// <remarks/> public byte SupplierID { get { return this.supplierIDField; } set { this.supplierIDField = value; } } /// <remarks/> public byte CategoryID { get { return this.categoryIDField; } set { this.categoryIDField = value; } } /// <remarks/> public byte QuantityPerUnit { get { return this.quantityPerUnitField; } set { this.quantityPerUnitField = value; } } /// <remarks/> public ushort UnitPrice { get { return this.unitPriceField; } set { this.unitPriceField = value; } } /// <remarks/> public byte UnitsInStock { get { return this.unitsInStockField; } set { this.unitsInStockField = value; } } /// <remarks/> public byte UnitsOnOrder { get { return this.unitsOnOrderField; } set { this.unitsOnOrderField = value; } } /// <remarks/> public byte ReorderLevel { get { return this.reorderLevelField; } set { this.reorderLevelField = value; } } /// <remarks/> public bool Discontinued { get { return this.discontinuedField; } set { this.discontinuedField = value; } } /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public byte Discount { get { return this.discountField; } set { this.discountField = value; } } public override string ToString() { return $"{ProductID} {ProductName} {UnitPrice:C}"; } } }
bookproduct类:
using System; using System.Collections.Generic; using System.Text; namespace ObjectToXmlSerializationSample { public class BookProduct:Product { private string isbnField; /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string Isbn { get { return this.isbnField; } set { this.isbnField = value; } } } }
inventory类:
using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization; namespace ObjectToXmlSerializationSample { [XmlRoot] public class Inventory { [XmlArrayItem("Product", typeof(Product)), XmlArrayItem("Book", typeof(BookProduct))] public Product[] InventoryItems { get; set; } public override string ToString() { var outText = new StringBuilder(); foreach (Product prod in InventoryItems) { outText.AppendLine(prod.ProductName); } return outText.ToString(); } } }
序列化对象:
public static void SerializeInventory() { var product = new Product() { ProductID=100, ProductName="Product Thing", SupplierID=10 }; var book = new BookProduct() { ProductID = 101, ProductName = "how to use your new product thing", SupplierID=10, Isbn="123456789" }; Product[] products = new Product[] { product, book }; var inventory = new Inventory() { InventoryItems=products }; //第一种 FileStream stream = File.OpenWrite("inventory.xml"); using (TextWriter writer = new StreamWriter(stream)) { XmlSerializer serializer = new XmlSerializer(typeof(Product)); serializer.Serialize(writer, inventory); } //第二种 //using (FileStream stream = File.Create("inventory.xml")) { // XmlSerializer serializer = new XmlSerializer(typeof(Inventory)); // serializer.Serialize(stream, inventory); //} }
反序列化对象:
public static void DeserializeInventory() { //第一种 using (FileStream stream = File.OpenRead("inventory.xml")) { XmlSerializer serializer = new XmlSerializer(typeof(Inventory)); Inventory inventory= serializer.Deserialize(stream) as Inventory; foreach (Product product in inventory.InventoryItems) { System.Console.WriteLine(product.ProductName); } } //第二种 using (var stream = new FileStream("inventory.xml", FileMode.Open)) { var serializer = new XmlSerializer(typeof(Product)); Inventory inventory = serializer.Deserialize(stream) as Inventory; foreach (Product product in inventory.InventoryItems) { System.Console.WriteLine(product.ProductName); } } }