1. 前言
XML,全称为可扩展标记语言(eXtensible Markup Language),是一种用于描述、传输和存储数据的语言。它被设计用来传输和存储数据,与 HTML 不同,XML 的主要目的不在于显示数据,而是强调数据的结构性。XML 使用类似 HTML 的标签表示数据的结构和其他信息。
2. 优缺点
- XML的优点:
- 易于人类阅读和编写:XML文档的格式清晰、易于理解,方便人们进行编辑和查看。
- 跨平台性:XML使用Unicode编码,具有跨平台性,可以在不同的操作系统、编程语言和地区之间进行数据交换。
- 可扩展性:XML可以自定义标签,适用于不同领域的扩展和定制,具有较强的灵活性。
- 强大的查询和操作能力:XML文档的结构化特性使其可以方便地被计算机程序解析和查询,支持XPath等查询语言,方便进行数据操作。
- XML的缺点:
- 冗余数据:XML文档在描述数据时会产生大量的冗余数据,尤其是在数据量较大的情况下,会导致文件体积较大。
- 性能问题:XML文档的解析和查询操作需要一定的时间和计算资源,在处理大量数据时可能会影响性能。
- 安全性问题:XML文档可能包含恶意代码,如XSS攻击等,需要注意安全性问题。
- 不适用于所有数据类型:XML不适用于存储所有类型的数据,例如二进制文件、大文本文件等不适合用XML存储。
3. 解析
- 格式模板
<?xml version="1.0" encoding="UTF-8"?> <root> <element1>内容1</element1> <element2 attribute1="value1">内容2</element2> <element3 attribute2="value2"> <subelement>子内容</subelement> </element3> </root>
3.1 XmlDocument
3.1.1 优缺点
- 优点:
- 易于使用:XmlDocument提供了大量的方法和属性,可以方便地操作和查询XML文档。它提供了对整个XML文档的树形结构进行遍历和查询的能力,使用户可以轻松地获取XML文档中的节点、属性、文本等内容。
- 内存占用较小:XmlDocument将整个XML文档加载到内存中,因此适用于处理较小的XML文件。由于整个XML文档被加载到内存中,用户可以快速地访问和查询XML文档中的任意节点,而不需要进行磁盘I/O操作。
- 缺点:
- 处理大型文件时可能会遇到性能问题:由于XmlDocument将整个XML文档加载到内存中,因此在处理大型XML文件时可能会遇到性能问题。大量的XML数据可能会导致内存溢出或性能下降。
- 不适用于流式处理:XmlDocument适用于一次性解析整个XML文档,而不适用于流式处理。如果需要按需读取XML文档中的节点,XmlDocument可能不是最佳选择。
3.1.2 解析
- 读取:
//1.读取XML文件 //XmlDocument xml = new XmlDocument(); //读取文本方式1-xml.LoadXml(传入xml文本字符串) //读取文本方式2-xml.Load(传入路径) //2.读取元素和属性 //获取单个节点 : XmlNode node = xml.SelectSingleNode(节点名) //获取多个节点 : XmlNodeList nodeList = xml.SelectNodes(节点名) //获取节点元素内容:node.InnerText //获取节点元素属性: //1.item.Attributes["属性名"].Value //2.item.Attributes.GetNamedItem("属性名").Value //通过迭代器遍历或者循环遍历XmlNodeList对象 可以获取到各单个元素节点 XmlDocument doc = new XmlDocument(); doc.Load("example.xml"); XmlNode root = doc.DocumentElement; XmlNode node = root.SelectSingleNode("//player"); string name = node.Attributes["name"].Value; int age = int.Parse(node.Attributes["age"].Value); Debug.Log("Name: " + name); Debug.Log("Age: " + age);
- 写入:
//关键类 XmlDocument 用于创建节点 存储文件 //关键类 XmlDeclaration 用于添加版本信息 //关键类 XmlElement 节点类 XmlDocument doc = new XmlDocument(); XmlElement root = doc.CreateElement("game"); XmlElement player = doc.CreateElement("player"); player.SetAttribute("name", "John"); player.SetAttribute("age", 25); root.AppendChild(player); doc.AppendChild(root); doc.Save("example.xml");
3.2 XmlTextReader和XmlTextWriter
XMLTextReader 这个类设计的目的就是从XML文件中快速的读取数据,而对系统资源(主要包括内存和处理器时间)不做很高的要求。
3.2.1 优缺点
- 优点:
- 适用于流式处理:XmlTextReader适用于按需读取XML文档中的节点,适用于流式处理大型XML文件。通过逐个读取XML文档中的节点,XmlTextReader可以避免一次性加载整个XML文件到内存中,从而减少内存占用和提高处理性能。
- 性能较好:由于XmlTextReader采用了事件驱动的模型,因此可以更好地利用系统资源,提高处理性能。事件驱动模型使得XmlTextReader可以更加高效地处理大型XML文件,同时减少CPU和内存的使用。
- 缺点:
- 事件驱动模型需要更多代码:相比XmlDocument类,XmlTextReader需要更多的代码来实现对XML文档的解析和处理。使用XmlTextReader进行XML解析需要编写更多的代码来处理事件触发和节点读取。
- 不易于处理属性值:XmlTextReader对于属性值的处理不如XmlDocument方便,需要更多的代码来实现。使用XmlTextReader读取属性值时,需要额外编写代码来获取节点的属性并处理它们。
- 它是只读的,仅向前的,不能在文档中执行向后导航操作
3.2.2 解析
- XmlTextReader读取:
static void XmlTextReaderTest() { XmlTextReader textReader = new XmlTextReader(filePath3); textReader.WhitespaceHandling = WhitespaceHandling.None; while (textReader.Read()) { if (textReader.NodeType == XmlNodeType.Element) { if (reader.Name == "player") { string name = reader.GetAttribute("name"); int age = int.Parse(reader.GetAttribute("age")); Debug.Log("Name: " + name); Debug.Log("Age: " + age); } } if (textReader.NodeType == XmlNodeType.Text) { } if (textReader.NodeType == XmlNodeType.EndElement) { } } //读取完毕后要记得关闭流,否则会占用文档,无法被其它线程打开 textReader.Close(); }
- XmlTextWriter写入:
XmlTextWriter writer = new XmlTextWriter("example.xml", System.Text.Encoding.UTF8); writer.WriteStartElement("game"); writer.WriteStartElement("player"); writer.WriteAttributeString("name", "John"); writer.WriteAttributeString("age", 25); writer.WriteEndElement(); // player writer.WriteEndElement(); // game writer.Close();