文件系统数据 及 XML部分
________________
1. 流
流:
是序列化设备的抽象表示。序列化设备可以 以线性方式存储 和访问数据,一次一个字节。
设备可以是 磁盘文件、网络通道、内存位置 或 其他支持线性方式的对象。
把设备变成抽象的,可以隐藏底层目标 和 源。抽象的级别 便于 代码重用,使用流可以忽略设备的物理机制。
类的类型:
输出流:向目标写入数据时,用输出流。
输入流:将数据读取到内存 或 变量中,用输入流。
________________
2. 用于输入和输出的类
System.IO名称空间包含几乎所有的类。 下图中橙色的部分,将会做介绍
类 说明
Path 实用类,用于处理路径名称
Directory 静态使用类,用于移动、复制和删除目录
File 静态使用类,用于移动、复制和删除文件
FileInfo 表示磁盘上的物理文件。要对文件读写,需要创建Stream对象
DirectoryInfo 表示磁盘上的物理目录,包含处理目录的方法
FileStreamInfo FileInfo和DirectoryInfo的基类
FileStream 表示可读、可写、可读性的 文件。文件可进行同步 或 异步读写
StreamReader 从流中读 字符 数据
StreamWriter 向流中写 字符 数据
FileSystem Watcher 用于监控文件和目录,提供了发生变化时可捕获的事件。
File类 和 Directory类:
File类的常用静态方法:Copy(), Create(), Delete(), Open(), Move()
Directroy类的常用静态方法:CreateDirectory(), Delete(), GetDirectories(), GetFiles(), GetFiles(), GetFilesSystemEntries(), Move()
FileInfo类:
这个类不是静态的。
创建一个FileInfo对象:
FileInfo aFile = new FileInfo(@"C:/Log.txt");
可以指定目录名,但这不是很有效,因为这样会用所有的目录信息初始化FileInfo的基类FilesSystemInfo,但FilesInfo中与文件相关的专用方法或属性不会工作。
File 与 FileInfo:
File类是静态的,不需要声明对象就可以使用;而FileInfo需要声明对象。
·如果仅进行单一方法调用,则可以使用File类,因为不必实例化对象
·如果在文件上执行几种操作,最后用FileInfo类,因为对象已经在文件系统上引用了正确的文件;静态类每次操作都要寻找文件。
例:
使用FileInfo类:
FileInfo aFile = new FileInfo("Data.txt");
if(aFile.Exists)
Console.WriteLine("File Exists");
使用File类:
if(File.Exists("Data.txt")) Console.WriteLine("File Exists");
FileInfo提供了与底层文件相关的属性,这些熟悉继承于FileSystemInfo基类,所有可以应用于File类 和 Directory类。
FileSystemInfo的属性 说明
Atrributes 使用FileAttributes枚举,获取或者设置当前文件或目录的属性
CreationTime 获取文件创建日期
Extension 只读属性,用来提取文件扩展名
Exists 判断文件是否存在,是只读抽象属性,在FileInfo和DirectoryInfo里有重写
FullName 只读属性,检索文件的完整路径,
LastAccessTime 获取或设置上次访问文件的日期和时间
LastWriteTime 获取或设置上次写入文件的日期和时间
Name 检索文件的完整路径。只读抽象属性,在FileInfo和DirectoryInfo中有重写
FileInfo专用的属性 说明
Directory 只读属性,检索一个DirectoryInfo对象,表示包含当前文件的目录。
DirectoryName 只读属性,返回文件目录的路径。
IsReadOnly 文件只读书性的快捷方式。也可通过Atrributes来访问
Length 只读属性,获取文件的容量,字节为单位,返回long值。
DirectoryInfo类:
Directory类 和 DirectoryInfo类的选中方式 与 Files 和 FileInfol的选则方式相同。
DirectoryInfo类也继承自FileSystemInfo,只是这些属性是应用于目录的。
DirectoryInfo的两个专用属性:
Parent:只读属性,检索一个DirectoryInfo对象,表示包含当前目录的目录;
Root:只读属性,检索一个DirectoryInfo对象,表示包含当前目录的根目录,比如:C:/ 。
路径名相对路径:
可以用Directory.GetCurrentDirectory()找出工作目录的当前设置,也可以用Directory.SetCurrentDirectory()设置新路径。
上移目录可以用.. 比如:../Log.txt
上移两个目录: ../../Log.txt
FileStream类:
FileStream类 与 Stream类:
FileStream表示磁盘或网络路径上指向文件的流。类中提供了读写字节的方法。
但当经常使用StreamReader 或 StreamWrite执行读写功能。因为Stream类操作的是字符数据。
-------------------------------------------
FileStream构造函数之一:FileStream aFile = new FilesStream(filename, FileMode.Member);
FileStream构造函数之二:FileStream aFile = new FilesStream(filename,FileMode.Member,FileAccess.Member);
FileMode枚举成员:
FileMode枚举成员 文件存在 文件不存在
Append 打开文件,流指向文件末尾,只能与FileAccess.Write联合使用 创建一个新文件。只能与FileAccess.Write联合使用
Create 删除该文件,然后创建新文件 创建新文件
CreateNew 抛出异常 创建新文件
Open 打开现有的文件,流指向文件开头 抛出异常
OpenOrCreate 打开文件,流指向文件的开头 创建新文件
Truncate 打开现有文件,清楚其内容。流指向文件开头,保留文件的初始创建日期 抛出异常
FileAccess枚举成员:
Read:打开文件,用于只读; Write:打开文件,用于只写; ReadWrite:打开文件,用于读写。
----------------------------------------------
创建FileStream对象的快捷方式:
File和FileInfo类都提供了OpenRead()和OpenWrite()方法,可以提供快捷方式,前者只读,后者只写。
例:
用File类:
FileStream aFile = File.OpenRead("Data.txt");
用FileInfo类:
FileInfo aFileInfo = new FileInfo("Data.txt");
FileStream aFile = aFileInfo.OpenRead();
--------------------------------------------------------------------------------
文件中位置:
FileStream类维护内部文件指针,指向进行下一个读写操作的位置。;
大多时候,打开文件时,指针指向文件开始位置;
该指针可以用Seek()fangf修改。
aFile.Seek( 8 ,SeekOrigin.Begin);
第一个参数: 以字节为单位的移动距离;可以定负查找位置,如:-5。
第二个参数: 开始计算的其实位置。SeekOrigin枚举的值:Begin,Current,End。
注意:读写文件时,文件指针也会改变。
------------------------------------------------------------
读取数据:
FileStream类只能处理原始字节,所以,它可以处理任何数据文件,比如,声音、图像文件。
FileStream类不能直接读入字符串,需要转换;StreamReader类可以处理读入字符串。
例:
byte[] byData = new byte[200];
char[] charData = new char[200];
FileStream aFile = new FileStream("../../Program.cs, FileMode.Open"); //创建FileStream对象
aFile.Seek(113,SeekOrigin.Begin); //先用FileStream.Seek()方法在文件指向要操作的位置,修改指针。
aFile.Read(byData, 0 ,200); //FileSteam.Read()方法时访问数据的主要手段
Decoder d = Encoding.UTF8.GetDecoder(); //Decoder类在System.Text名称空间中
d.GetChars(byData, 0, byData.Length, charData, 0); // 调用GetChars方法,将字节数据转换成字符
..............
FileSteam.Read()方法的三个参数:
参数一: 传入的 字节数组;
参数二: 字节数组中开始写入数据的位置;
参数三: 从文件中读入多少字节。
-------------------------------------------------------------
写入数据:
1)构建要写入文件的字符数组;
2)用Encoder对象转换为字节数组;
3)调用Write()方法。
例:
charData = "hi! how are you doing?".ToCharArray();
byData = new byte[charData.Length];
Encoder e = Encoding.UTF8.GetEncoder();
e.GetBytes(charData, 0 ,charData.Length, byData, 0, true);
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0 , byData.Length);
StreamWriter类:
创建对象:
方法一,有FileSreame对象时,
FileStream aFile = new FileStream("Log.txt", FileMode.CreateNew);
StreamWriter sw = new StreamWriter(aFile);
方法二,直接从文件中创建:
StreamWriter sw = new StreamWriter("Log.txt", true); //true,打开文件,保留原数据。false的话,创建新文件,或截取现有文件并打开。
StreamWriter没有属性FileAccess & FileMode,如果要使用这些参数,就要使用第一种创建方法,用FileStream构造函数指定这些属性。
例:
FileStream aFile = new FileStream("Log.txt", FileMode.OpenOrCreate); //用FileStream方法设置高级参数(指FileAccess & FileMode属性)
StreamWriter sw = new StreamWriter(aFile);
sw.Write("Hello to you"); //向文件中写入数据
sw.Close();
StreamReader类:
创建对象的方式和StreamWriter类一样:
例:
FileStream aFile = new FileStream("Log.txt", FileMode.Open);
StreamReader sr = new StreamReader(aFile);
或,
StreamReader sr = new StreamReader("Log.txt");
读取数据:
ReadLine()方法:
string strline = sr.ReadLine(); //StreamReader.ReadLine()读取回车之前的文本,当到达文件尾时,返回空值。
while(strline != null)
{
Console.WriteLine(strline);
strline = sr.ReadLine();
}
sr.Close();
Read()方法:
int nChar = sr.Read(); //此方法,将流的下一个字符作为正整数返回,如果达到结尾处,则返回-1.
while(nChar != -1)
{
Console.Write(Convert.ToChar(nChar)); //Convert把值转换为字符
sr.Read();
}
sr.Close();
ReadToEnd()方法:
strline = sr.ReadToEnd(); //读取整个文件,并将其作为字符串返回。文件太大的,最好不要用。
Console.WriteLine(strline);
读取分隔符分隔的文件的算法:
逗号是最常见的分隔符,Excel、Access、SQL Server的数据都可以导出为用逗号分隔的CSV文件。
例:
下面的程序,是将分隔符文件中的数据,转换成 如下所示的转换后的数据。
分隔符文件:
ProductID,Name,Price
1,Spiky Pung,1000
2,Gloop Galloop Soup,25
4,Hat Sauce,12
转换后:
List«Dictionary«string, string»» {
{Dictionary«"ProductID","1"», Dictionary«"Name","Spiky Pung"» , Dictionary«"Price","1000"»},
{Dictionary«"ProductID","2"», Dictionary«"Name","Gloop Galloop Soup"», Dictionary«"Price","25"»},
{Dictionary«"ProductID","4"», Dictionary«"Name","Hat Sauce"», Dictionary«"Price","12"»}
}
代码:
private static List«Dictionary«string,string»» GetData(out List«string» columns)
{
string strLine; //存放读取出来的字符串
string[] strArray; //存放split之后的字符串
char[] charArray = new char[] {','}; //设定Split方法的参数
List«Dictionary«string, string»» data = new List«Dictionary«string, string»»(); //存放处理后的数据
columns = new List«string»();
try
{
FileStream aFile = new FileStream("../../SomeData.txt", FileMode.Open);
StreamReader sr = new StreamReader(aFile);
strLine = sr.ReaderLine();
strArray = strLine.Split(charArray); //分割列名
for(int x=0; x«=strArray.GetUpperBound(0); x++) //GetUpperBound(0)获得第一组字符串的大小
{
columns.Add(strArray[x]); //将分割好的列名 添加到 columns
}
strLine = sr.ReadLine();
while(strLine != null)
{
strArray = strLine.Split(charArray); //分割每一行的数据
Dictionary«string,string» dataRow = new Dictionary«string,string» (); //创建以Dictionary«column,value»形式存储的 对象(dataRow)
for(int x=0; x«=strArray.GetUpperBound(0); x++)
{
dataRow.Add(columns[x], strArray[x]);
}
data.Add(dataRow); //将整理好的一组数据,添加到Dictionary 的List中
strLine = sr.ReadLine();
}
sr.Close();
return data; //return
}
}
catch (IOException ex)
{
......
return data;
}
XML是一种存储和传输数据的优秀的方法,而CSV文件仍然非常普遍,还会使用相当长的时间。
读写压缩文件:
GZIP 或 Deflate算法都是公开的,免费的。
System.IO.Compression名称空间中有两个压缩流类 DeflateStream 和 GZipStream。
下面介绍的是简单的,将文本数据保存在压缩文件中。但不能再外部程序中访问这个文件。
压缩数据:
static void SaveCompressedFile(string filenmae, string data)
{
FileStream fileStream = new FileStream(filename, FileName.Create, FileAccess.Write); //1.创建文件流对象
GZipStream compressionStream = new GZipstream(fileStream, CompressionMode.Compress); //2.用文件流初始压缩流类
StreamWriter writer = new StreamWriter(compressionStream); //3.将压缩流对象用于 StreamWriter
writer.Write(data); //4.执行压缩流操作
writer.Close(); //5.关闭对象
}
解压缩数据:
步骤与压缩数据相同。
static void LoadCompressionFile(string filename)
{
FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
GZipStream compressionStream = new GZipStream(fileStream, CompressionMode.Decompress);
StreamReader reader = new StreamReader(compressionStream);
string data = reader.ReadToEnd();
reader.Close();
return data;
}
________________
3. 序列化对象
在System.Runtime.Serialization和System.Runtime.Serialization.Formatters名称空间 中提供了 序列化对象的基础架构。
Framework中有两种实现方式:
System.Runtime.Serialization.Formatters.Binary:包含了BinaryFormatter类,可以在 对象 和 二进制 之间进行序列化;
System.Runtime.Serialization.Formatters.Soap:包含SoapFormatter类,可以在 对象 和 SOAP格式的XML数据 之间进行序列化。
这两个类都实现了IFormatter接口:
IFormatter提供的方法 说明
void Serialize(Stream stream, object source) 把source序列化为stream
object Deserialize(Stream stream) 解序stream中的数据,返回得到的对象
BinaryFormatter的序列化 与 解序:
序列化:
IFormatter serializer = new BinaryFormatter();
serializer.Serialize(myStream, myObject);
解序:
IFormatter serializer = new BinaryFormatter();
MyObjectType myNewObject = serializer.Deserialize(myStream) as MyObjectType;
[Serializable]属性& [NonSerialized]属性:
.NET Framework要求把对象标记为可序列化,用[Serializable]属性;
把不想序列化的成员用[NonSerialized]属性标记,没有序列化的成员在序列化存储的时候,不会和其他成员一起存储,即,这部分数据没有存储起来。
这些属性并没有由派生类继承,每个要序列化的类,都必须应用这些属性。
例:
创建可序列化的类
[Serializable] //将这个类标记为可序列化
public class Product
{
public long ID;
public string Name;
public double Price;
[NonSerialized] //将Notes这个成员标记为不可序列化
String Notes;
public Product(long id, string name , double price, string notes)
{ ........}
public override string ToString()
{
return string.Format("{0}: {1} (${2:F2}) {3}", ID,Name,Price,Notes);
}
}
执行序列化代码
.......
using System.IO; //序列化需要的三个名称空间
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
static void Main(string[] args)
{
List«Product» products = new List«Product»(); //创建要序列化的对象
products.Add( new Product(1,"Spiky Pung", 1000.0, "Good stuff"));
products.Add( new Product(2,"Gloop Galloop Soup", 25.0, "Tasty"));
//序列化
IForamtter serializer = new BinaryFormatter(); //1.实例化接口对象
FileStream saveFile = new FileStream("Products.bin", FileMode.Create, FIleAccess.Write); //2.创建流
serializer.Serialize(saveFile, products); //3.执行序列化方法
saveFile.Close(); //关闭流
................
//解序
FileStream loadFile = new FileStream("Products.bin", FileMode.Open, FileAccess.Read); //2.创建流
List«Product» savedProducts = serlializer.Deserialize(loadFile) as List«Product»; //3.执行序列化方法
loadFile.Close(); //关闭流
//显示解序的对象
foreach(Product product in savedProducts)
{
Console.WriteLine(product);
}
}
显示结果:
1: Spiky Pung ($1000.0) //值注意的是Notes字段的内容被丢弃了,因为这个成员没有被序列化
2: Gloop Galloop Soup ($25.0)
________________
4.监控文件结构
使用类FileSystemWatcher监控文件。使用该类的过程:
1)设置属性,指定监控的位置、内容、要处理事件的时间
2)提供事件处理程序的地址
4)打开FileSystem Watcher,等待事件
属性:
Path:设置监控的 文件 或 目录(监控整个目录的文件)的位置
NotifyFilter:枚举值Attributes, CreationTime, DirectoryName, FileName, LastAccess, LastWrite, Security, Size.可以通过OR来合并枚举值。
这些表示要监控的文件或目录的属性,如果变化,引发相应事件。
Filter:监控文件的过滤器,比如:*.txt
4个事件:Changed, Created, Deleted, Renamed
EnableRaisingEvents属性:设为true,打开监控。
例:
using System.IO;
.....
private FileSystemWatcher watcher; //添加监控类对象
//初始化对象
this.watcher = new System.IO.FileSystemWatcher();
this.watcher.Deleted += new System.IO.FileSystemEventHanlder(this.OnDelete); //绑定事件处理程序 OnDelete()
.....
this.watcher.Created += new System.IO.FileSystemEventHanlder(this.OnCreate);
//事件处理程序
public void OnDelete(Object source, FileSystemEventsArgs e)
{............}
........
//设置属性
private void cmdWatch_Click(object sender, EventArgs e) //一个Button的事件处理程序,用来配置FileSystemWatcher的属性,并打开监控
{
watcher.Path = Path.GetDirectoryName(txtLocation.Text); // txtLocation.Text = FileDialog.FileName,在File对话框中赋值(省略了这部分代码)
watcher.Filter = Path.GetFileName(txtLocation.Text); // Path.GetFilleName是System.IO中的方法,Path是静态类。
watcher.NotifyFilter = NotifyFilters.LastWrite|NotifyFilters.FileName|NotifyFilters.Size;
watcher.EnableRaisingEvents = true;
}
________________
5. XML文档
XML元素名称区分大小写。
XML元素不允许重叠。
所有元素必须有闭元素,有一个特例,“空”元素,比如:«book /»
节点:元素,元素内的文本,属性都是节点。
关于属性:
用属性存储数据:
«book title="Tristam Shandy"» «/book»
用元素存储数据:
«book»
«title»Tristram Shandy«/title»
«/book»
用 属性 和 用 元素 没有区别,都可以。
XML声明:
简单的声明: «?xml version="1.0" ?»
声明中可选属性:encoding--设置文档的字符集 & standalone--yes or no,表示文档是否依赖其他文件。
XML文档的结构:
XML最重要的一点是 提供了 结构化的组织数据的方式。(不同于关系数据库)
XML文档必须有一个根元素,如果文档的顶级有多个元素,就是不合法XML文档,但在顶级可以包括其他XML节点(通常是XML声明)。
XML文档不需要任何预定义的结构。这是传统关系数据库和XML的主要区别之一。
XML名称空间:
名称空间的语法:«areslab:book» 表示wrox名称空间中的«book»元素
为保证名称空间的唯一性,可以把前缀映射到URI上(Uniform Resource Identifier)。URI最常见的类型是web地址。
例:
«?xml version="1.0"?»
«books»
«book xmlns:areslab="http://www.areslab.com"» //使用xmlns:prefix属性,将其设置为标识名称空间的唯一URI。
«worx:title» Begining C#«/worx:title» //用前缀表示唯一的名称空间
«worx:author»Karli Watson«/worx:author»
«book»
«/books»
默认名称空间:
没有前缀,定义默认名称空间,不需要前缀标识。
«? xml version="1.0"?»
«books»
«book xmlns="http://www.areslab.com"»
«title»Begining C#«/title»
«author»Karli Watson«/author»
«/book»
«/books»
格式良好并有效的XML:
遵循XML的文档要求如下:
1)有且只有一个根元素
2)每个元素都有闭标记(简短语法除外)
3)没有重叠元素
4)所以属性必须放在引号内
验证XML文档:
除了符合XML标准外,XML文档还必须符合应用程序所做的规定。
验证XML需要指定规则方式。
XML支持两种方法:DTD 和模式。DTD在.net 中用的不多。
模式:
.NET支持的模式: XSD(XML Schema Definition,一个开放标准,推荐) 和 XDR(XML-Data Reduced,专用于微软,用的不多)
模式可以包括在XML文档中,也可以放在单独的文件里。
XSD模式中的元素必须属于名称空间http://www.w3.org/2001/XMLSchema。
«schema xmlns="http://www.w3.org/2001/XMLSchema"» //在某个模式文档*.xsd文件中
XSD模式文档的样例在P652.
XML文档与另一个文件中的XSD模式关联,需要在XML文档的根元素中添加schemalocation元素。
«?xml version="1.0"?»
«books schemalocation="file://C:/****/books.xsd"» //books是根元素,"file:/C:/**/books.xsd"是创建好的XSD模式文件
.......
«/books»
用VS创建XSD模式文件:
在VS中可以基于XML文档创建XSD模式,而不需要自己编写。
1)创建XML文档
2)点击菜单中的XML|Create Schema(创建架构)。
________________
6. 在应用程序中使用XML
XML文档对象模型:
XML文档对象模型(Document Object Model,DOM)是一组处理和访问XML的类。
DOM的类在名称空间System.Xml中:
类名 说明
XmlNode 表示文档树种的一个节点,如果这个节点表示根,就可以导航到任何位置
XmlDocument XmlDocument扩展了XmlNode类,用于加载,保存磁盘或其他地方的数据
XmlElement XmlElement表示一个元素,派生于XmlLinkedNode(派生于XmlNode)
XmlAttribute 表示一个属性,派生于XmlNode类
XmlText 表示开标记和闭标记之间的文本
XmlComment 表示一种特殊类型的节点,这种节点不是文档的一部分,但为渎职提供部分信息
XmlNodeList 表示j
XmlDocument类:
使用XmlDocument类把XML文件加载到内存;
然后,从中获得根节点;
读取和处理XML数据。
例:
using System.Xml;
.....
XmlDocument document = new XmlDocument(); //创建实例
document.Load(@"C:/****/books.xml"); //加载文件
这个还负责维护XML结构,一些方法还用于创建,删除,修改节点。
XmlElement类:
XmlDocument的DocumentElement属性返回一个XmlElement实例,表示XmlDocument的根节点。
接上面的代码:
XmlElement element = document.DocumentElement; //返回根节点
XmleElement的属性:
属性名 说明
FistChild 返回根节点之后第一个子节点。
返回一个XmlNode对象,需要测试类型,可能是XmlText类型or XmlElement类型
LastChile 返回当前节点的最后一个子节点
ParentNode 返回当前节点的父节点
NextSibling 返回有相同父节点的下一个节点
HasChildNodes 检查是否有子元素
例:
XmlDocument document = new XmlDocument();
document.Load(@"C:/***/books.xml");
XmlNode root = (XmlNode)document.DocumentElemet; //XmlNode & XmlElment表示的是整个节点,而不仅仅是标记中的文本
if(root==null) return;
if(root is XmlElement)
{
.......
if(root.HasChildNodes) { ....... }
if(root.NextSibling) { ....... }
}
else if(root is XmlText) { sting text = (XmlText)root.value; ....... }
修改节点的值:
XmlText节点的实例的value属性可以获取节点值。
value属性 可以 获取 XmlText, XmlComment,XmlAtrribute类的文本。
XmlElement类用 InnerText 和 InnerXml方法可以获取标记之间的值。
InnerText :返回去掉标记后连接起来的字符串,
InnerXml:返回带标记的连接起来的字符串。
插入新节点:
1)创建节点
XmlDocument的方法可以创建新的XmlNode 和 XmlElement实例(这两个类只有一个受保护的构造函数,所以不能用new)
方法名 说明
CreateNode 创建任意类型的节点,可以创建XmlNodeType枚举的所有类型,返回XmlNode实例
CreateElement 只能创建XmlDocument类型的节点
CreateAtrribute 只能创建XmlAtrribute类型的节点
CreateTextNode 创建XmlTextNode类型的节点
CreateComment 创建注释
2)执行操作
派生于XmlNode的类(包括XmlDocument 和 XmlElement)中的方法
方法名 说明
AppendChild 追加子节点到节点列表最后
InsertAfter 可以控制插入新节点的位置,插到指定位置之后
InsertBefore 插到指定位置之前
例:
private void buttonCreateNode_Click(object sender, EventArgs e)
{
XmlDocument document = new XmlDocument(); //创建对象,加载XML文件
document.Load(@"C:/***/book.xml");
XmlElement root = document.DocumentElement; //获取根节点
XmlElement newBook = document.CreateElement("book"); //创建节点
XmlElement newTitle = document.CreateElement("title");
....
XmlText title = document.CreateTextNode("Begining C#"); //插入XmlText类节点
.....
XmlComment comment = document.CreateComment("This book is ...."); //插入注释
newBook.AppendChild(comment); //插入节点
....
newBook.AppendChild(title);
....
root.InsertAfter(newBook, root.FirstChild);
document.Save(@"C:/****/book.xml"); //存储文件
}
删除节点:
派生于XmlNode的所有类都包含删除节点的方法:
RemoveAll:删除所有子节点;
RemoveChild:删除一个子节点,后悔了key
例:删除最后一个子节点
XmlDocument document = new XmlDocument();
document.Load(@"C:/***/book.xml");
XmlElement root = document.DocumentElement;
if(root.HasChildNodes)
{
XmlNode book = root.LastChild;
root.RemoveChild(book);
document.Save(@"C:/**/book.xml");
}
选择节点:
XmlNode类选择节点的方法:
SelectSingleNode:选择一个节点,如果创建查找多个节点的查询,就只返回第一个节点;
SelectNodes:以XmlNodesList类的形式返回一个节点集合。
XPath:
XPath是XML文档的查询语言,就行SQL是关系数据库的查询语言一样。
XPath常见操作
目的 XPath查询示例
选择当前节点 .
选当前节点的父节点 ..
选当前节点的所有子节点 *
选择特定名称的所有子节点,这里是title(限定特定名称) title
选择但前节点的一个属性 @pages
选择当前节点的所有属性 @*
按照索引选择一个子节点,这里是第二个author节点 author[2]
选择当前节点的所有文本节点 text()
选择当前节点的一个或多个孙子节点 author/text()
在文档中选特定名称的所有节点,这里找所有的title节点 //title
在文档中选择特定父节点下特定名称的所有节点 //book/title
选择值满足条件的节点 //book[author='sephiroth']
选择属性值满足条件的节点 //book[@pages='1000']
例:
private XmlDocument mDocument;
private XmlNode mCurrentNode;
mDocument = new XmlDocument();
mDocument.Load(@"C:/****/book.xml");
mCurrentNode = mDocument.DocumentElement;
mCurrentNode = mDocument.DocumentElement.SelectSingleNode("//books"); //应用查询方法SelectSingleNode,//books为XPath查询语,参上表
________________