# XML
- XML 指的是可扩展标记语言(eXtensible Markup Language)
- XML 被设计用来传输和存储数据,其焦点是数据的内容。HTML 则用来表现数据,其焦点是数据的外观。
- XML 在 Web 中起到的作用接近于 HTML。XML 是各种应用程序之间进行数据传输的最常用的工具。
- XML 数据能够存储在独立的.xml 文件中。
- XML 是独立于软件和硬件的信息传输工具。
# XML 的用途
- XML 规定了文本的编辑格式,统一格式可以简化数据共享、简化数据传输、简化平台变更
- XML 可以分离数据和其它逻辑(例:更改某个数值时,不需要更改源码,只需要更改 XML 文件中的记录即可)
# XML 树结构
- XML 将数据组织成为一棵树,它从 “根部” 开始,扩展到 “枝叶”。
- 利用缩进表示层级关系
| 所有的节点均以<name>开头,以</name>结尾 | |
| <?xml version="1.0" encoding="UTF-8"?>  XML声明。它声明XML的版本(1.0)和所使用的编码(UTF-8) | |
| <root_CharacterTemplateData>  根节点。xml必须包含根节点,该节点是所有其他节点的父节点。 | |
|   <CharacterTemplateData id="0" name="xml">  子节点,id和name是子节点的属性 | |
| <JobID>1</JobID> 子节点的子节点,1 是节点值 | |
| <JobMode>none</JobMode> | |
| <InitForce>1.1</InitForce> | |
|   </CharacterTemplateData> | |
| </root_CharacterTemplateData> | 
# XML 语法
# 版本和编码的信息可以省略
- 默认编码是:UTF-8
- UTF-8 也是 HTML5, CSS, JavaScript, PHP, 和 SQL 的默认编码。
| <?xml version="1.0" encoding="UTF-8"?> | 
# 所有的 XML 元素都必须有一个关闭标签
| 所有的节点均以<name>开头,以</name>结尾 | |
| <name>1</name> | 
# xml 必须包含根节点,该节点是所有其他节点的父节点
| root是根节点 | |
| <root> | |
| <child>1</child> | |
| </root> | 
# 大小写敏感
| 以下二者是不同的 | |
| <name>1</name> | |
| <Name>1</Name> | 
# 必须正确嵌套
| <a><b>Test</b></a> 正确嵌套 | |
| <a><b>Test</a></b> 这是错误的 | 
# 属性值必须加引号
| <Test id="0" name="xml"></Test> | 
# 特殊符号
- xml 中有一些特殊符号不能直接使用
- 使用预定义符号代替这些特殊符号
| 预定义符号 | 特殊符号 | 解释 | 
|---|---|---|
| < | < | 小于 | 
| > | > | 大于 | 
| & | & | 与 | 
| ' | ' | 单引号 | 
| " | " | 双引号 | 
# XML 中的注释
| <!-- annotate --> | 
# 在 XML 中,空格会被保留
- XML 文档中的空格不会被删减
- HTML 会把多个连续的空格字符裁减(合并)为一个
# XML 元素
XML 元素指的是从开始标签到结束标签的部分(包括开始标签和结束标签)
XML 元素可以包含一下内容
- 其他元素内容
- 属性
- 文本内容
XML 命名规则
- 名称可以包含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字母 xml(或者 XML、Xml 等等)开始
- 名称不能包含空格
- 名称不能直接使用 xml 特殊符号(如:“<”)
- 名称应避免使用某些符号(如:“-”、“.”、“:”),它们在不同的软件中可能会有不同的定义
# XML 属性
属性提供有关元素的额外信息(例如:ID 属性用于标识 XML 元素)。没有什么规矩可以告诉我们什么时候使用属性,什么时候使用元素。因为属性难以阅读和维护,所以应该避免使用它。如果信息看起来像是数据,那就使用元素吧。
# 使用 CSharp 创建、更改、读取 XML
| using System.Xml; | |
| public class Program | |
| { | |
|     /// <summary> | |
|     /// 文件路径 | |
|     /// </summary> | |
| private static string Path = "C:/Users/25417/Desktop/Test.xml"; | |
|     /// <summary> | |
|     /// 创建 XML | |
|     /// </summary> | |
| private static void CreateXML() | |
|     { | |
|         // 检查 xml 是否存在,如果没有文件则创建 | |
| if (File.Exists(Path)) | |
|         { | |
| Console.WriteLine("The file already exists: " + Path); | |
| return; | |
|         } | |
|         // 创建 xml 实例 | |
| XmlDocument xmlDoc = new XmlDocument(); | |
|         // 创建根节点 | |
| XmlElement root = xmlDoc.CreateElement("root_CharacterTemplateData"); | |
|         // 在 xml 实例中追加根节点 | |
| xmlDoc.AppendChild(root); | |
|         // 创建一级子节点 | |
| XmlElement elmNew = xmlDoc.CreateElement("CharacterTemplateData"); | |
|         // 设置一级子节点的两个属性 | |
| elmNew.SetAttribute("id", "0"); | |
| elmNew.SetAttribute("name", "xml"); | |
|         // 在跟节点中追加一级节点 | |
| root.AppendChild(elmNew); | |
|         // 创建二级节点 | |
| XmlElement jobID = xmlDoc.CreateElement("JobID"); | |
|         // 设置二级节点值 | |
| jobID.InnerText = "1"; | |
|         // 在一级节点中追加二级节点 | |
| elmNew.AppendChild(jobID); | |
| XmlElement jobMode = xmlDoc.CreateElement("JobMode"); | |
| jobMode.InnerText = "none"; | |
| elmNew.AppendChild(jobMode); | |
| XmlElement initForce = xmlDoc.CreateElement("InitForce"); | |
| initForce.InnerText = "1.1"; | |
| elmNew.AppendChild(initForce); | |
|         // 保存 xml 文件 | |
| xmlDoc.Save(Path); | |
|     } | |
|     /// <summary> | |
|     /// 添加 XML | |
|     /// </summary> | |
| private static void AddXML() | |
|     { | |
| if (!File.Exists(Path)) | |
|         { | |
| Console.WriteLine("The file does not exist: " + Path); | |
| return; | |
|         } | |
|         // 创建 xml 实例 | |
| XmlDocument xmlDoc = new XmlDocument(); | |
|         // 读取 xml 文件 | |
| xmlDoc.Load(Path); | |
|         // 找到指定的节点 | |
| XmlNode root = xmlDoc.SelectSingleNode("root_CharacterTemplateData"); | |
| XmlElement elmNew = xmlDoc.CreateElement("CharacterTest"); | |
| elmNew.SetAttribute("id", "1"); | |
| root.AppendChild(elmNew); | |
| XmlElement elmNew_0 = xmlDoc.CreateElement("CharacterTest_0"); | |
| elmNew_0.InnerText = "2"; | |
| elmNew.AppendChild(elmNew_0); | |
| xmlDoc.Save(Path); | |
|     } | |
|     /// <summary> | |
|     /// 更改 XML | |
|     /// </summary> | |
| private static void ChangeXML() | |
|     { | |
| if (!File.Exists(Path)) | |
|         { | |
| Console.WriteLine("The file does not exist: " + Path); | |
| return; | |
|         } | |
| XmlDocument xmlDoc = new XmlDocument(); | |
| xmlDoc.Load(Path); | |
| XmlNode root = xmlDoc.SelectSingleNode("root_CharacterTemplateData"); | |
|         // 遍历并获取 XmlElement 类型的子节点,因为 XmlNode 中没有 SetAttribute () 方法 | |
| foreach (XmlElement item in root.ChildNodes) | |
|         { | |
|             // 更改 XML | |
| if (item.Name == "CharacterTemplateData" && | |
| item.GetAttribute("id") == "0") | |
|             { | |
|                 // 更改节点属性 | |
| item.SetAttribute("id", "1"); | |
|                 // 更改子节点值 | |
| XmlNode jobID = item.SelectSingleNode("JobID"); | |
| jobID.InnerText = "2"; | |
|             } | |
|             // 删除 XML 中的内容 | |
| if (item.Name == "CharacterTest" && | |
| item.HasAttribute("id")) | |
|             { | |
|                 // 删除属性 | |
| item.RemoveAttribute("id"); | |
|                 // 删除子节点 | |
| XmlNode test_0 = item.SelectSingleNode("CharacterTest_0"); | |
| item.RemoveChild(test_0); | |
|                 // 删除全部 | |
|                 //item.RemoveAll(); | |
|                 //item.RemoveAllAttributes(); | |
|             } | |
|         } | |
| xmlDoc.Save(Path); | |
|     } | |
|     /// <summary> | |
|     /// 读取 XML | |
|     /// </summary> | |
| private static void ReadXML() | |
|     { | |
| if (!File.Exists(Path)) | |
|         { | |
| Console.WriteLine("The file does not exist: " + Path); | |
| return; | |
|         } | |
| XmlDocument xmlDoc = new XmlDocument(); | |
| xmlDoc.Load(Path); | |
|         // 获取根节点 | |
| XmlElement root = xmlDoc.DocumentElement; | |
| Console.WriteLine("rootName: " + root.Name); | |
|         // 遍历根节点的子节点 | |
| foreach (XmlElement item in root.ChildNodes) | |
|         { | |
| Console.WriteLine(item.Name); | |
|             // 遍历属性 | |
| foreach (XmlAttribute attribute in item.Attributes) | |
|             { | |
| Console.WriteLine("Attribute_" + attribute.Name + ": " + attribute.InnerText); | |
|             } | |
|             // 遍历子节点的子节点 | |
| foreach (XmlElement childNode in item.ChildNodes) | |
|             { | |
| Console.WriteLine("ChildNode_" + childNode.Name + ": " + childNode.InnerText); | |
|             } | |
|         } | |
|     } | |
| public static void Main() | |
|     { | |
| CreateXML(); | |
| AddXML(); | |
| ChangeXML(); | |
| ReadXML(); | |
|     } | |
| } | 
