# XML与JSON
XML和JSON都是数据语言,以规定的格式来存储数据。C# .Net应用都使用XML以某种形式来存储数据,比如配置文件,XAML文件主要用在WPF和Windows Store应用的用户界面描述上。本章重点介绍XML,简单介绍XAML。
# XML基础
XML(Extensible Markup Language)可扩展标记语言是一种数据语言,它将数据以一种简单的文本格式存储,它是一种W3C标准格式,类似于HTML。它的细节很复杂,但大多数任务不需要了解XML的详细知识。
元素和属性是XML的两大组成要素之一,元素是<elementName>,属性则是<elementName prop="propValue">。
# XML模式
XML文档可用XML模式来描述,XML模式也是一个XML文档,但它描述的是一个XML文档的结构,即元素和属性,可以根据XML模式来验证XML文档,在C#中XML模式格式是XSD(XML Schema Definition)。
# XML文档模型
XML文档对象模型(Document Object Model,DOM)是能使程序有能力动态的访问和更新文档的内容,结构的接口。构成DOM的类在System.Xml名称空间中,它常见的几个类如下:
类名 | 说明 |
---|---|
XmlNode | 表示文档树的一个节点,它是很多类的基类,如果它是文档的根节点,可以从它导航到文档任意位置 |
XMLDocument | 扩展了XmlNode,通常是使用XML的第一个对象,用于加载磁盘或其他地方的数据,并保存数据 |
XmlElement | 表示XML文档中的一个元素,派生于XmlLinkedNode,XmlLinkedNode派生于XmlNode |
XmlAttribute | 表示一个特性,跟XMLDocument类一样,它也派生于XmlNode类 |
XmlText | 表示开始标记和结束标记之间的文本 |
XmlComment | 表示一种特殊的节点,这个节点不是文档的一部分,但为阅读器提供文档的各部分信息 |
XmlNodeList | 表示一个节点集合 |
下面我们用程序来获取并分析一个XML文件结构:
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load(@"Test.xml");
XmlElement element = document.DocumentElement;
GetALLXmlStructure(element);
}
static void GetALLXmlStructure(XmlElement element)
{
Console.WriteLine($"current node Name:{element.Name}!--------");
Console.WriteLine($"current node InnerXml:{element.InnerXml}");
Console.WriteLine($"current node InnerText:{element.InnerText}");
Console.WriteLine($"current node type:{element.NodeType}");
Console.WriteLine($"current node value:{element.Value}");
void GetChildNode(XmlNodeList xmlNodeList, int level = 0)
{
level++;
string tempIntentStr = new string(' ', level*4);
foreach(XmlNode xmlOne in xmlNodeList)
{
Console.WriteLine(tempIntentStr + $"current node Name:{xmlOne.Name}!--------");
//Console.WriteLine(tempIntentStr + $"current node InnerXml:{xmlOne.InnerXml}");
//Console.WriteLine(tempIntentStr + $"current node InnerText:{xmlOne.InnerText}");
Console.WriteLine(tempIntentStr + $"current node type:{xmlOne.NodeType}");
Console.WriteLine(tempIntentStr + $"current node value:{xmlOne.Value}");
if (xmlOne.Attributes != null)
{
foreach(XmlAttribute oneAttr in xmlOne.Attributes)
{
Console.WriteLine(tempIntentStr+$"have attributes:{oneAttr.Name},value:{oneAttr.Value}");
}
}
if (xmlOne.HasChildNodes)
{
GetChildNode(xmlOne.ChildNodes,level);
}
}
}
if (element.HasChildNodes)
{
GetChildNode(element.ChildNodes);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
通过上面的分析发现:
- InnerText获取当前节点中所有子节点的文本,把它作为一个串联字符串返回。
- InnerXml属性返回包括xml标记的文本。
- value能有返回值得类只有XmlText,XmlComment,XmlAttribute。
然后我们根据上面的分析来写一个输出xml文件的输出程序:
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load(@"Test.xml");
XmlElement element = document.DocumentElement;
Console.WriteLine(GetAllXmlFileContent(element));
}
static string GetAllXmlFileContent(XmlElement element)
{
string returnCode = "\r\n";
string resultStr = "";
void GetXmlContent(XmlNode xmlNode, int level = -1)
{
level++;
string tempIntentStr = new string(' ', level*2);
if(xmlNode is XmlComment)
{
resultStr += tempIntentStr + $"<!--{xmlNode.Value}-->{returnCode}";
return;
}
resultStr += tempIntentStr+"<"+xmlNode.Name;
//分析是否有属性
if (xmlNode.Attributes != null)
{
foreach (XmlAttribute oneAttr in xmlNode.Attributes)
{
resultStr += $" {oneAttr.Name}=\"{oneAttr.Value}\"";
}
}
resultStr += ">";
if (xmlNode.HasChildNodes)
{
if(xmlNode.ChildNodes.Count == 1 && xmlNode.ChildNodes[0] is XmlText) {
resultStr += xmlNode.ChildNodes[0].Value+$"</{xmlNode.Name}>{returnCode}";
}
else
{
resultStr += returnCode;
foreach (XmlNode xmlOne in xmlNode.ChildNodes)
{
//Console.WriteLine("enter node:" + xmlOne.Name);
GetXmlContent(xmlOne,level);
}
resultStr += tempIntentStr+$"</{xmlNode.Name}>{returnCode}";
}
}
}
GetXmlContent(element);
return resultStr;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
下面是对DOM节点的一些增删改查:
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load(@"Test.xml");
XmlElement element = document.DocumentElement;
Console.WriteLine("--------------原文本内容:-------------------");
Console.WriteLine(GetAllXmlFileContent(element));
Console.WriteLine("--------------得到某个节点的值-------------");
Console.WriteLine("返回当前节点之后的第一个子节点");
Console.WriteLine(element.ChildNodes[0].FirstChild.InnerXml);
Console.WriteLine("返回当前节点之后的最后一个子节点");
Console.WriteLine(element.ChildNodes[0].LastChild.InnerXml);
Console.WriteLine("返回当前节点的父节点");
Console.WriteLine(element.ChildNodes[0].LastChild.ParentNode.InnerXml);
Console.WriteLine("返回当前节点有相同父节点的下一个兄弟节点");
Console.WriteLine(element.ChildNodes[0].NextSibling.InnerXml);
Console.WriteLine("-----------------修改第一个子节点的值后----------------");
element.ChildNodes[0].FirstChild.FirstChild.Value = "Ceshi";
Console.WriteLine(element.ChildNodes[0].FirstChild.InnerXml);
Console.WriteLine("---------------删除第二个子节点--------------------");
XmlNode deleteNode = element.RemoveChild(element.ChildNodes[1]);
Console.WriteLine(GetAllXmlFileContent(element));
Console.WriteLine("---------------将删除的子节点再插入原文档--------------");
element.AppendChild(deleteNode);
Console.WriteLine(GetAllXmlFileContent(element));
Console.WriteLine("---------------创建新的节点并插入----------------------");
XmlElement newNode = document.CreateElement("student");
newNode.SetAttribute("status", "ready");
XmlElement nameNode = document.CreateElement("name");
nameNode.AppendChild(document.CreateTextNode("This is person info"));
newNode.AppendChild(nameNode);
newNode.InsertBefore(document.CreateComment("测试注释"),newNode.ChildNodes[0]);
element.InsertAfter(newNode, element.ChildNodes[1]);
Console.WriteLine(GetAllXmlFileContent(element));
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# XPath搜索XML
XPath的示例操作如下:
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load(@"Test.xml");
XmlNode xmlNode1 = document.SelectSingleNode("//person[@p='123']");
Console.WriteLine(xmlNode1.InnerXml);
Console.WriteLine("----------------select person node--------------");
XmlNodeList xnl = document.SelectNodes("//person");
if(xnl.Count>0)
foreach (XmlNode one in xnl){
Console.WriteLine(one.InnerXml);
}
Console.WriteLine("select node");
Console.WriteLine(document.SelectSingleNode("//person[age='22']").InnerXml);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# JSON基础
JSON是JavaScript Object Notation,它比XML要简洁的多,它是web传输过程中最常用的轻量级的文本数据交换格式。JavaScript能够使用内置的eval()函数用JSON数据来生成原生的JavaScript对象。它源于JavaScript但是独立于语言和平台,很多语言都支持这种格式。
# XML转换成JSON
可以通过NuGet Package Manager安装一个Newtonsoft JSON.NET包:
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
document.Load(@"Test.xml");
string json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(document);
Console.WriteLine(json);
}
2
3
4
5
6
7
← C#基础13-文件 C#基础15-LINQ →