C# 3

简介: 文件系统数据 及 XML部分 ________________1. 流     流:          是序列化设备的抽象表示。序列化设备可以 以线性方式存储 和访问数据,一次一个字节。

文件系统数据 及 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查询语,参上表         
________________

目录
相关文章
|
6天前
|
NoSQL Cloud Native Redis
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
阿里云瑶池数据库团队后续将持续参与Valkey社区,如过往在Redis社区一样耕耘,为开源社区作出持续贡献。
Redis核心开发者的新征程:阿里云与Valkey社区的技术融合与创新
|
6天前
|
关系型数据库 分布式数据库 数据库
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
PolarDB分布式版助力《香肠派对》实现百亿好友关系20万QPS的毫秒级查询。
PolarDB闪电助攻,《香肠派对》百亿好友关系实现毫秒级查询
|
7天前
|
消息中间件 Cloud Native Serverless
RocketMQ 事件驱动:云时代的事件驱动有啥不同?
本文深入探讨了云时代 EDA 的新内涵及它在云时代再次流行的主要驱动力,包括技术驱动力和商业驱动力,随后重点介绍了 RocketMQ 5.0 推出的子产品 EventBridge,并通过几个云时代事件驱动的典型案例,进一步叙述了云时代事件驱动的常见场景和最佳实践。
115049 1
|
8天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101814 1
|
7天前
|
自然语言处理 Cloud Native Serverless
通义灵码牵手阿里云函数计算 FC ,打造智能编码新体验
近日,通义灵码正式进驻函数计算 FC WebIDE,让使用函数计算产品的开发者在其熟悉的云端集成开发环境中,无需再次登录即可使用通义灵码的智能编程能力,实现开发效率与代码质量的双重提升。
95388 2
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
112734 12
|
12天前
|
SQL 存储 JSON
Flink+Paimon+Hologres 构建实时湖仓数据分析
本文整理自阿里云高级专家喻良,在 Flink Forward Asia 2023 主会场的分享。
71322 1
Flink+Paimon+Hologres 构建实时湖仓数据分析
|
16天前
|
弹性计算 运维 安全
访问控制(RAM)|云上程序使用临时凭证的最佳实践
STS临时访问凭证是阿里云提供的一种临时访问权限管理服务,通过STS获取可以自定义时效和访问权限的临时身份凭证,减少长期访问密钥(AccessKey)泄露的风险。本文将为您介绍产品原理,以及具体的使用步骤。
151046 4
|
15天前
|
监控 负载均衡 Java
深入探究Java微服务架构:Spring Cloud概论
**摘要:** 本文深入探讨了Java微服务架构中的Spring Cloud,解释了微服务架构如何解决传统单体架构的局限性,如松耦合、独立部署、可伸缩性和容错性。Spring Cloud作为一个基于Spring Boot的开源框架,提供了服务注册与发现、负载均衡、断路器、配置中心、API网关等组件,简化了微服务的开发、部署和管理。文章详细介绍了Spring Cloud的核心模块,如Eureka、Ribbon、Hystrix、Config、Zuul和Sleuth,并通过一个电商微服务系统的实战案例展示了如何使用Spring Cloud构建微服务应用。
103519 9
|
15天前
|
Java 数据处理 调度
更高效准确的数据库内部任务调度实践,阿里云数据库SelectDB 内核 Apache Doris 内置 Job Scheduler 的实现与应用
Apache Doris 2.1 引入了内置的 Job Scheduler,旨在解决依赖外部调度系统的问题,提供秒级精确的定时任务管理。