XML(Extensible Markup Language)可扩展的标记语言
1.文档头部声明:
<?xml version="1.0" encoding="utf-8" ?>
?XML标记说明它是一个XML文档,version为版本号,encoding属性表明是编码格式为”utf-8”,standalone取”yes”时,表明该文件未引用其它外部文件。
2.注释:
<!--下面是学生名单-->
注释的格式和html类似:<!--“注释的内容”-->,使用注释时需要注意:1.注释不可以出现在XML声明之前.2.注释中不可以出现”--”字符,如:<!--下面是学生--名单> 3.注释不可以嵌套.
3.根元素:
<学生名单> XXX </学生名单>
每个文档必须有有一个根元素,没有根元素将会在解析的时候出现错误
4.元素(标记),是XML中用来定义数据的一个基本的单位,元素是由标记要定义的,同时标记分为非空标记和空标记:
(1)非空标记
<学号>201701</学号>
<姓名>张三三</姓名>
<班级>0102</班级>
非空即当标记中包含有内容,格式为:<标记>内容<标记>
(2)空标记
<学生 id=”1”></学生>
空标记中只有属性,两个标签中的内容是为空的。
XML位于System.Xml命名空间,以下为XML结构列表:
标 记 |
描 述 |
XmlDocument |
XML文档 |
XmlNode |
XML中单个的节点,如<学生名单> |
XmlAttribute |
XML元素中的属性 |
XmlText |
表示元素或属性的文本内容 |
XmlElement |
最小元素,如<姓名>张三三</姓名> |
XmlComment |
表示XML注释的内容 |
XmlDeclaration |
XML文档第一行的声明 |
XML文档的创建
最终效果:
<?xml version="1.0" encoding="UTF-8"?>
<学生名单>
<学生 id="1">
<姓名>张三三</姓名>
</学生>
</学生名单>
//创建一个XML文档对象
XmlDocument doc = new XmlDocument();
//声明XML头部信息
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
//添加进doc对象子节点
doc.AppendChild(dec);
//创建根节点
XmlElement root = doc.CreateElement("学生名单");
doc.AppendChild(root);
//再创建根节点下的子节点
XmlElement student = doc.CreateElement("学生");
//设置子节点属性
student.SetAttribute("id", "1");
//子节点下再创建标记
XmlElement studentName = doc.CreateElement("姓名");
//<姓名>的内容
XmlText xmlText = doc.CreateTextNode("张三三");
//将内容添加到<姓名>标记
studentName.AppendChild(xmlText);
//再将<姓名>标记添加到<学生>标记的子节点下
student.AppendChild(studentName);
//最后把<学生>标记添加到根节点<学生名单>子节点下
root.AppendChild(student);
//doc文档对象保存写入
doc.Save("Student.xml");
总结:创建一个xml
1 创建一个XML文档对象 new XmlDocument
2 声明XML头部信息 doc.CreateXmlDeclaration("1.0", "UTF-8", null);
3 创建根节点 doc.CreateElement("学生名单");
4 再创建根节点下的子节点 doc.CreateElement("学生");
5 设置子节点属性 student.SetAttribute("id", "1");
6 子节点下再创建标记 doc.CreateElement("姓名");
7 创建标记的内容 doc.CreateTextNode("张三三");
8 最后把头部信息,根节点加入到doc,把根节点下的节点加入到根节点,一一归属
XML文档的读取
C#中XML读取有三种方式,XmlDocument,XmlTextReader,Linq to Xml
//获取<学生>子节点
XmlNodeList personNodes = root.GetElementsByTagName("学生");
//使用foreach循环读出集合
foreach (XmlNode node in personNodes)
{
string id = ((XmlElement)node).GetAttribute("id");
string name = ((XmlElement)node).GetElementsByTagName("姓名")[0].InnerText;
}
总结:
1 加载根目录下XML文件 doc.Load("XMLFile1.xml");
2 //获取根节点 XmlElement root = doc.DocumentElement;
3 //获取<学生>子节点 root.GetElementsByTagName("学生");
4 使用foreach循环读出集合 GetAttribute 读属性,GetElementsByTagName读标签
增加
XmlDocument doc = new XmlDocument();
//加载根目录下XML文件
doc.Load(xmlPath);
//获取根节点
XmlElement root = doc.DocumentElement;
XmlElement student = doc.CreateElement("学生");
root.AppendChild(student);
//最后一步不要忘记了保存
doc.Save(xmlPath);
1 读取xml
2 获取根节点 doc.DocumentElement;
3 加入创建的新节点 AppendChild
4 重新保存
//筛选出符合条件的标记
XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@id='4']");
//获取该标记下的子元素
XmlElement nameEle = (XmlElement)selectEle.GetElementsByTagName("姓名")[0];
//修改<姓名>标记中的内容
nameEle.InnerText = "大明";
//还是那句话不要忘记保存
doc.Save(xmlPath);
1 搜索 SelectSingleNode
2 获取 GetElementsByTagName
3 修改 InnerText
4 保存
删除标记
删除和修改类似,也是筛选出符合条件的标记,然后移除
//筛选出符合条件的标记
XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@id='4']");
//删除指定子元素
root.RemoveChild(selectEle);
//还是那句话不要忘记保存
doc.Save(xmlPath);
1 搜索
2 删除
3 保存
最后发现序列化能加快开发进度,使用序列化
序列化
方法的使用
指定可以序列化的对象的类型。
XmlSerializer serializer = new XmlSerializer(o.GetType());
使用流和配置文件创建一个新的XmlWriter实例。从而把序列化的类写入流中
using( XmlWriter writer = XmlWriter.Create(stream, settings) ) {
serializer.Serialize(writer, o);
}
创建内存流并读取
using( MemoryStream stream = new MemoryStream() ) {
using( StreamReader reader = new StreamReader(stream, encoding) ) {
return reader.ReadToEnd();
}
}
创建文件流
using( FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write) ) { }
读取文件流
File.ReadAllText(path, encoding);
基本思路:
序列化:
序列化为xml字符串:1 把对象序列化为xml格式的内存流,再写入,再读取出来。
序列化为文件:1 把对象序列化为xml格式的文件流,再写入进去。
反序列化为对象 把字符串转化为内存流,再读取出来,最后转化为对象
文件反序列化为对象 把文件里面的字符串读取出来,把字符串转化为内存流,再读取出来,最后转化为对象
默认情况下(不加任何Attribute),类型中的属性或者字段,都会生成XmlElement。
比如:
public int IntValue { get; set; }
class XmlHelper
{
private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding)
{
if (o == null)
throw new ArgumentNullException("o");
if (encoding == null)
throw new ArgumentNullException("encoding");
XmlSerializer serializer = new XmlSerializer(o.GetType());
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.NewLineChars = "\r\n";
settings.Encoding = encoding;
settings.IndentChars = " ";
using (XmlWriter writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, o);
writer.Close();
}
}
/// <summary>
/// 将一个对象序列化为XML字符串
/// </summary>
/// <param name="o">要序列化的对象</param>
/// <param name="encoding">编码方式</param>
/// <returns>序列化产生的XML字符串</returns>
public static string XmlSerialize(object o, Encoding encoding)
{
using (MemoryStream stream = new MemoryStream())
{
XmlSerializeInternal(stream, o, encoding);
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream, encoding))
{
return reader.ReadToEnd();
}
}
}
/// <summary>
/// 将一个对象按XML序列化的方式写入到一个文件
/// </summary>
/// <param name="o">要序列化的对象</param>
/// <param name="path">保存文件路径</param>
/// <param name="encoding">编码方式</param>
public static void XmlSerializeToFile(object o, string path, Encoding encoding)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write))
{
XmlSerializeInternal(file, o, encoding);
}
}
/// <summary>
/// 从XML字符串中反序列化对象
/// </summary>
/// <typeparam name="T">结果对象类型</typeparam>
/// <param name="s">包含对象的XML字符串</param>
/// <param name="encoding">编码方式</param>
/// <returns>反序列化得到的对象</returns>
public static T XmlDeserialize<T>(string s, Encoding encoding)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentNullException("s");
if (encoding == null)
throw new ArgumentNullException("encoding");
XmlSerializer mySerializer = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(encoding.GetBytes(s)))
{
using (StreamReader sr = new StreamReader(ms, encoding))
{
return (T)mySerializer.Deserialize(sr);
}
}
}
/// <summary>
/// 读入一个文件,并按XML的方式反序列化对象。
/// </summary>
/// <typeparam name="T">结果对象类型</typeparam>
/// <param name="path">文件路径</param>
/// <param name="encoding">编码方式</param>
/// <returns>反序列化得到的对象</returns>
public static T XmlDeserializeFromFile<T>(string path, Encoding encoding)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
if (encoding == null)
throw new ArgumentNullException("encoding");
string xml = File.ReadAllText(path, encoding);
return XmlDeserialize<T>(xml, encoding);
}
}
参考文献: