C# 如何操作XML

Xml是扩展标记语言的简写,是一种开发的文本格式。关于它的更多情况可以通过w3组织了解http://www.w3.org/TR/1998/REC-xml-19980210。如果你不知道它,那你就out太多了。
.Net是如何处理Xml的?

通过XmlDocument读写Xml文档
有如下一段Xml:
 
<?xmlversion="1.0"encoding="utf-8"?>

<students>

  <!--我是一段注释文字-->

  <studentname="张平">

    <courses>

      <coursename="语文?">

        <teacherComment>

          <![CDATA[

        这里是语文老师的批注

        ]]>

        </teacherComment>     

    </course>

 

      <coursename="数学">

        <teacherComment>

          <![CDATA[

        这里是数学老师的批注

        ]]>

        </teacherComment>

      </course>

    </courses>

  </student>

</students>

 
1.如何使用XmlDocument读取Xml

我要用一段代码遍历所有Student,并打印Student的所有属性和子节点的值
using System;

using System.Collections.Generic;

using System.Text;

using System.Xml;

 

namespaceXmlExample

{

    classProgram

    {

        staticvoidMain(string[] args)

        {

            stringxmlFilePath =@"X:\about.net\example\XmlExample\1.xml";

            XmlDocument doc =newXmlDocument();

            doc.Load(xmlFilePath);

 

            //使用xpath表达式选择文档中所有的student子节点

            XmlNodeList studentNodeList = doc.SelectNodes("/students/student");

            if(studentNodeList !=null)

            {

                foreach(XmlNode studentNodeinstudentNodeList)

                {

                    //通过Attributes获得属性名字为name的属性

                    stringname = studentNode.Attributes["name"].Value;

                    Console.WriteLine("Student:"+ name);

 

                    //通过SelectSingleNode方法获得当前节点下的courses子节点

                    XmlNode coursesNode = studentNode.SelectSingleNode("courses");

 

                    //通过ChildNodes属性获得courseNode的所有一级子节点

                    XmlNodeList courseNodeList = coursesNode.ChildNodes;

                    if(courseNodeList !=null)

                    {

                        foreach(XmlNode courseNodeincourseNodeList)

                        {

                            Console.Write("\t");

                            Console.Write(courseNode.Attributes["name"].Value);

                            Console.Write("老师评语");

                            //通过FirstNode属性可以获得课程节点的第一个子节点,LastNode可以获得最后一个子节点

                            XmlNode teacherCommentNode = courseNode.FirstChild;

                            //读取CData节点

                            XmlCDataSection cdata = (XmlCDataSection)teacherCommentNode.FirstChild;

                            Console.WriteLine(cdata.InnerText.Trim());

                        }

                    }

                }

            }

 

            Console.Write("\r\nPress any key to continue....");

            Console.Read();

        }

    }

}

XmlDocument本身是从XmlNode继承的,读Xml节点可以通过FirstChild,LastChild,或者NextSibling,PreviousSibling读取单个节点,或者通过ChildNodes读取所有子节点。还可以使用XPath表达式使用SelectNodes(string xpath)或者SelectSingleNode(string xpath)读取单个或者多个符合条件的节点。
2.如何通过XmlDocument编辑Xml
同样是读取Xml中的xml例子,我们这次要用csharp代码生成xml,如下代码:
/*玉开博客 http://www.cnblogs.com/yukaizhao/ */

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml;

 

namespaceWriteXml

{

    classProgram

    {

        staticvoidMain(string[] args)

        {

            XmlDocument xmlDoc =newXmlDocument();

            //创建Xml声明部分,即<?xml version="1.0" encoding="utf-8" ?>

            xmlDoc.CreateXmlDeclaration("1.0","utf-8","yes");

 

            //创建根节点

            XmlNode rootNode = xmlDoc.CreateElement("students");

 

            //创建student子节点

            XmlNode studentNode = xmlDoc.CreateElement("student");

            //创建一个属性

            XmlAttribute nameAttribute = xmlDoc.CreateAttribute("name");

            nameAttribute .Value ="张同学";

            //xml节点附件属性

            studentNode.Attributes.Append(nameAttribute);

 

            

            //创建courses子节点

            XmlNode coursesNode = xmlDoc.CreateElement("courses");

            XmlNode courseNode1 = xmlDoc.CreateElement("course");

            XmlAttribute courseNameAttr = xmlDoc.CreateAttribute("name");

            courseNameAttr.Value ="语文";

            courseNode1.Attributes.Append(courseNameAttr);

            XmlNode teacherCommentNode = xmlDoc.CreateElement("teacherComment");

            //创建Cdata块

            XmlCDataSection cdata = xmlDoc.CreateCDataSection("<font color=\"red\">这是语文老师的批注</font>");

            teacherCommentNode.AppendChild(cdata);

            courseNode1.AppendChild(teacherCommentNode);

            coursesNode.AppendChild(courseNode1);

            //附加子节点

            studentNode.AppendChild(coursesNode);

 

            rootNode.AppendChild(studentNode);

            //附加根节点

            xmlDoc.AppendChild(rootNode);

 

            //保存Xml文档

            xmlDoc.Save(@"d:\test.xml");

 

            Console.WriteLine("已保存Xml文档");

 

 

        }

    }

}

使用XmlDocument生成xml的要点在于使用xmlDocument的实例的CreateElement创建XmlNode或者通过CreateAttribute方法创建属性,并通过AppendChild方法附加xml节点,通过AppendAttribute附加Attribute到节点的属性集合。

 

一个XML Helper 示例

/// <summary>
    /// XmlHelper 的摘要说明。
    /// </summary>
    public class XmlHelper
    {
        public XmlHelper()
        {

        }

        public enum XmlType
        {
            File,
            String
        };

        /// <summary>
        /// 创建XML文档
        /// </summary>
        /// <param name="name">根节点名称</param>
        /// <param name="type">根节点的一个属性值</param>
        /// <returns></returns>
        /// .net中调用方法:写入文件中,则:
        ///          document = XmlHelper.CreateXmlDocument("sex", "sexy");
        ///          document.Save("c:/bookstore.xml");         
        public static void CreateXmlDocument(string path)
        {
            var xmldoc = new XmlDocument();
            //加入XML的声明段落,<?xml version="1.0" encoding="utf-8"?>
            var xmldecl = xmldoc.CreateXmlDeclaration("1.0", "utf-8", null);
            xmldoc.AppendChild(xmldecl);

            加入一个根节点
            //var xmlelem = xmldoc.CreateElement("", "configuration", "");
            //xmldoc.AppendChild(xmlelem);

            xmldoc.Save(path);
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时返回该属性值,否则返回串联值</param>
        /// <returns>string</returns>
        /// /**************************************************
        /// * 使用示列:
        /// * XmlHelper.Read(path, "/Node", "")
        /// * XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")
        /// ************************************************/
        public static string Read(string path, string node, string attribute)
        {

            string value = "";

            try
            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                value = (attribute.Equals("") ? xn.InnerText : xn.Attributes[attribute].Value);

            }

            catch { }

            return value;

        }

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="element">元素名,非空时插入新元素,否则在该元素中插入属性</param>
        /// <param name="attribute">属性名,非空时插入该元素属性值,否则插入元素值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /// /**************************************************
        ///  * 使用示列:
        ///  * XmlHelper.Insert(path, "/Node", "Element", "", "Value")
        ///  * XmlHelper.Insert(path, "/Node", "Element", "Attribute", "Value")
        ///  * XmlHelper.Insert(path, "/Node", "", "Attribute", "Value")
        ///  ************************************************/
        public static void Insert(string path, string node, string element, string attribute, string value)
        {

            try
            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                if (element.Equals(""))
                {

                    if (!attribute.Equals(""))
                    {

                        XmlElement xe = (XmlElement)xn;

                        xe.SetAttribute(attribute, value);

                    }

                }

                else
                {

                    XmlElement xe = doc.CreateElement(element);

                    if (attribute.Equals(""))

                        xe.InnerText = value;

                    else

                        xe.SetAttribute(attribute, value);

                    xn.AppendChild(xe);

                }

                doc.Save(path);

            }

            catch { }

        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时修改该节点属性值,否则修改节点值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /// /**************************************************
        /// * 使用示列:
        /// * XmlHelper.Insert(path, "/Node", "", "Value")
        /// * XmlHelper.Insert(path, "/Node", "Attribute", "Value")
        /// ************************************************/
        public static void Update(string path, string node, string attribute, string value)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                XmlElement xe = (XmlElement)xn;
                if (attribute.Equals(""))
                    xe.InnerText = value;
                else
                    xe.SetAttribute(attribute, value);
                doc.Save(path);
            }
            catch { }
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时删除该节点属性值,否则删除节点值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /// /**************************************************
        /// * 使用示列:
        /// * XmlHelper.Delete(path, "/Node", "")
        /// * XmlHelper.Delete(path, "/Node", "Attribute")
        /// ************************************************/
        public static void Delete(string path, string node, string attribute)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                XmlElement xe = (XmlElement)xn;
                if (attribute.Equals(""))
                    xn.ParentNode.RemoveChild(xn);
                else
                    xe.RemoveAttribute(attribute);
                doc.Save(path);
            }
            catch { }
        }

        #region 读取XML资源到DataSet中

        /// <summary>

        /// 读取XML资源到DataSet中

        /// </summary>

        /// <param name="source">XML资源,文件为路径,否则为XML字符串</param>

        /// <param name="xmlType">XML资源类型</param>

        /// <returns>DataSet</returns>

        public static DataSet GetDataSet(string source, XmlType xmlType)
        {

            DataSet ds = new DataSet();

            if (xmlType == XmlType.File)
            {

                ds.ReadXml(source);

            }

            else
            {

                XmlDocument xd = new XmlDocument();

                xd.LoadXml(source);

                XmlNodeReader xnr = new XmlNodeReader(xd);

                ds.ReadXml(xnr);

            }

            return ds;

        }



        #endregion

        #region 操作xml文件中指定节点的数据

        /// <summary>

        /// 获得xml文件中指定节点的节点数据

        /// </summary>

        /// <param name="TableName"></param>

        /// <returns></returns>
        public static string GetNodeInfoByNodeName(string path, string nodeName)
        {

            string XmlString = "";

            XmlDocument xml = new XmlDocument();

            xml.Load(path);

            System.Xml.XmlElement root = xml.DocumentElement;

            System.Xml.XmlNode node = root.SelectSingleNode("//" + nodeName);

            if (node != null)
            {

                XmlString = node.InnerText;

            }

            return XmlString;

        }

        #endregion

        #region 获取一个字符串xml文档中的ds

        /// <summary>

        /// 获取一个字符串xml文档中的ds

        /// </summary>

        /// <param name="xml_string">含有xml信息的字符串</param>

        public static void get_XmlValue_ds(string xml_string, ref DataSet ds)
        {

            System.Xml.XmlDocument xd = new XmlDocument();

            xd.LoadXml(xml_string);

            XmlNodeReader xnr = new XmlNodeReader(xd);

            ds.ReadXml(xnr);

            xnr.Close();

            int a = ds.Tables.Count;

        }

        #endregion

        #region 读取XML资源到DataTable中

        /// <summary>

        /// 读取XML资源到DataTable中

        /// </summary>

        /// <param name="source">XML资源,文件为路径,否则为XML字符串</param>

        /// <param name="xmlType">XML资源类型:文件,字符串</param>

        /// <param name="tableName">表名称</param>

        /// <returns>DataTable</returns>

        public static DataTable GetTable(string source, XmlType xmlType, string tableName)
        {

            DataSet ds = new DataSet();

            if (xmlType == XmlType.File)
            {

                ds.ReadXml(source);

            }

            else
            {

                XmlDocument xd = new XmlDocument();

                xd.LoadXml(source);

                XmlNodeReader xnr = new XmlNodeReader(xd);

                ds.ReadXml(xnr);

            }

            return ds.Tables[tableName];

        }

        #endregion

        #region 读取XML资源中指定的DataTable的指定行指定列的值

        /// <summary>

        /// 读取XML资源中指定的DataTable的指定行指定列的值

        /// </summary>

        /// <param name="source">XML资源</param>

        /// <param name="xmlType">XML资源类型:文件,字符串</param>

        /// <param name="tableName">表名</param>

        /// <param name="rowIndex">行号</param>

        /// <param name="colName">列名</param>

        /// <returns>值,不存在时返回Null</returns>
        public static object GetTableCell(string source, XmlType xmlType, string tableName, int rowIndex, string colName)
        {

            DataSet ds = new DataSet();

            if (xmlType == XmlType.File)
            {

                ds.ReadXml(source);

            }

            else
            {

                XmlDocument xd = new XmlDocument();

                xd.LoadXml(source);

                XmlNodeReader xnr = new XmlNodeReader(xd);

                ds.ReadXml(xnr);

            }

            return ds.Tables[tableName].Rows[rowIndex][colName];

        }

        /// <summary>

        /// 读取XML资源中指定的DataTable的指定行指定列的值

        /// </summary>

        /// <param name="source">XML资源</param>

        /// <param name="xmlType">XML资源类型:文件,字符串</param>

        /// <param name="tableName">表名</param>

        /// <param name="rowIndex">行号</param>

        /// <param name="colIndex">列号</param>

        /// <returns>值,不存在时返回Null</returns>
        public static object GetTableCell(string source, XmlType xmlType, string tableName, int rowIndex, int colIndex)
        {

            DataSet ds = new DataSet();

            if (xmlType == XmlType.File)
            {

                ds.ReadXml(source);

            }

            else
            {

                XmlDocument xd = new XmlDocument();

                xd.LoadXml(source);

                XmlNodeReader xnr = new XmlNodeReader(xd);

                ds.ReadXml(xnr);

            }

            return ds.Tables[tableName].Rows[rowIndex][colIndex];

        }

        #endregion

        #region 将DataTable写入XML文件中

        /// <summary>

        /// 将DataTable写入XML文件中

        /// </summary>

        /// <param name="dt">含有数据的DataTable</param>

        /// <param name="filePath">文件路径</param>

        public static void SaveTableToFile(DataTable dt, string filePath)
        {

            DataSet ds = new DataSet("Config");

            ds.Tables.Add(dt.Copy());

            ds.WriteXml(filePath);

        }

        #endregion

        #region 将DataTable以指定的根结点名称写入文件

        /// <summary>

        /// 将DataTable以指定的根结点名称写入文件

        /// </summary>

        /// <param name="dt">含有数据的DataTable</param>

        /// <param name="rootName">根结点名称</param>

        /// <param name="filePath">文件路径</param>
        public static void SaveTableToFile(DataTable dt, string rootName, string filePath)
        {

            DataSet ds = new DataSet(rootName);

            ds.Tables.Add(dt.Copy());

            ds.WriteXml(filePath);

        }

        #endregion

        #region 使用DataSet方式更新XML文件节点
        /// <summary>

        /// 使用DataSet方式更新XML文件节点

        /// </summary>

        /// <param name="filePath">XML文件路径</param>

        /// <param name="tableName">表名称</param>

        /// <param name="rowIndex">行号</param>

        /// <param name="colName">列名</param>

        /// <param name="content">更新值</param>

        /// <returns>更新是否成功</returns>
        public static bool UpdateTableCell(string filePath, string tableName, int rowIndex, string colName, string content)
        {

            bool flag = false;

            DataSet ds = new DataSet();

            ds.ReadXml(filePath);

            DataTable dt = ds.Tables[tableName];



            if (dt.Rows[rowIndex][colName] != null)
            {

                dt.Rows[rowIndex][colName] = content;

                ds.WriteXml(filePath);

                flag = true;

            }

            else
            {

                flag = false;

            }

            return flag;

        }

        /// <summary>

        /// 使用DataSet方式更新XML文件节点

        /// </summary>

        /// <param name="filePath">XML文件路径</param>

        /// <param name="tableName">表名称</param>

        /// <param name="rowIndex">行号</param>

        /// <param name="colIndex">列号</param>

        /// <param name="content">更新值</param>

        /// <returns>更新是否成功</returns>
        public static bool UpdateTableCell(string filePath, string tableName, int rowIndex, int colIndex, string content)
        {
            bool flag = false;
            DataSet ds = new DataSet();
            ds.ReadXml(filePath);
            DataTable dt = ds.Tables[tableName];
            if (dt.Rows[rowIndex][colIndex] != null)
            {
                dt.Rows[rowIndex][colIndex] = content;
                ds.WriteXml(filePath);
                flag = true;
            }
            else
            {
                flag = false;
            }
            return flag;
        }

        #endregion

        #region 读取XML资源中的指定节点内容

        /// <summary>

        /// 读取XML资源中的指定节点内容

        /// </summary>

        /// <param name="source">XML资源</param>

        /// <param name="xmlType">XML资源类型:文件,字符串</param>

        /// <param name="nodeName">节点名称</param>

        /// <returns>节点内容</returns>
        public static object GetNodeValue(string source, XmlType xmlType, string nodeName)
        {

            XmlDocument xd = new XmlDocument();

            if (xmlType == XmlType.File)
            {

                xd.Load(source);

            }

            else
            {

                xd.LoadXml(source);

            }

            XmlElement xe = xd.DocumentElement;

            XmlNode xn = xe.SelectSingleNode("//" + nodeName);

            if (xn != null)
            {

                return xn.InnerText;

            }

            else
            {

                return null;

            }

        }



        /// <summary>

        /// 读取XML资源中的指定节点内容

        /// </summary>

        /// <param name="source">XML资源</param>

        /// <param name="nodeName">节点名称</param>

        /// <returns>节点内容</returns>
        public static object GetNodeValue(string source, string nodeName)
        {

            if (source == null || nodeName == null || source == "" || nodeName == "" || source.Length < nodeName.Length * 2)
            {

                return null;

            }

            else
            {

                int start = source.IndexOf("<" + nodeName + ">") + nodeName.Length + 2;

                int end = source.IndexOf("</" + nodeName + ">");

                if (start == -1 || end == -1)
                {

                    return null;

                }

                else if (start >= end)
                {

                    return null;

                }

                else
                {

                    return source.Substring(start, end - start);

                }

            }

        }

        #endregion

        #region 更新XML文件中的指定节点内容

        /// <summary>

        /// 更新XML文件中的指定节点内容

        /// </summary>

        /// <param name="filePath">文件路径</param>

        /// <param name="nodeName">节点名称</param>

        /// <param name="nodeValue">更新内容</param>

        /// <returns>更新是否成功</returns>
        public static bool UpdateNode(string filePath, string nodeName, string nodeValue)
        {

            bool flag = false;

            XmlDocument xd = new XmlDocument();

            xd.Load(filePath);

            XmlElement xe = xd.DocumentElement;

            XmlNode xn = xe.SelectSingleNode("//" + nodeName);

            if (xn != null)
            {

                xn.InnerText = nodeValue;

                flag = true;

            }

            else
            {

                flag = false;

            }

            return flag;

        }

        #endregion

        #region 对象化
        /// <summary>

        /// 读取xml文件,并将文件序列化为类

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <param name="path"></param>

        /// <returns></returns>
        public static T ReadXML<T>(string path)
        {

            XmlSerializer reader = new XmlSerializer(typeof(T));

            StreamReader file = new StreamReader(@path);

            return (T)reader.Deserialize(file);

        }

        /// <summary>

        /// 将对象写入XML文件

        /// </summary>

        /// <typeparam name="T">C#对象名</typeparam>

        /// <param name="item">对象实例</param>

        /// <param name="path">路径</param>

        /// <param name="jjdbh">标号</param>

        /// <param name="ends">结束符号(整个xml的路径类似如下:C:\xmltest\201111send.xml,其中path=C:\xmltest,jjdbh=201111,ends=send)</param>

        /// <returns></returns>
        public static string WriteXML<T>(T item, string path, string jjdbh, string ends)
        {

            if (string.IsNullOrEmpty(ends))
            {

                //默认为发送

                ends = "send";

            }

            int i = 0;//控制写入文件的次数,

            XmlSerializer serializer = new XmlSerializer(item.GetType());

            object[] obj = new object[] { path, "\\", jjdbh, ends, ".xml" };

            string xmlPath = String.Concat(obj);

            while (true)
            {

                try
                {

                    //用filestream方式创建文件不会出现“文件正在占用中,用File.create”则不行

                    FileStream fs;

                    fs = File.Create(xmlPath);

                    fs.Close();

                    TextWriter writer = new StreamWriter(xmlPath, false, Encoding.UTF8);

                    XmlSerializerNamespaces xml = new XmlSerializerNamespaces();

                    xml.Add(string.Empty, string.Empty);

                    serializer.Serialize(writer, item, xml);

                    writer.Flush();

                    writer.Close();

                    break;

                }

                catch (Exception exec)
                {

                    if (i < 5)
                    {

                        i++;

                        continue;

                    }

                    else

                    { break; }

                }

            }

            return SerializeToXmlStr<T>(item, true);

        }

        /// <summary>

        /// 静态扩展

        /// </summary>

        /// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征</typeparam>

        /// <param name="obj">需要序列化的对象</param>

        /// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>

        /// <returns></returns>
        public static string SerializeToXmlStr<T>(T obj, bool omitXmlDeclaration)
        {



            return XmlSerialize<T>(obj, omitXmlDeclaration);

        }
        #endregion

        #region XML序列化反序列化相关的静态方法

        /// <summary>

        /// 使用XmlSerializer序列化对象

        /// </summary>

        /// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征</typeparam>

        /// <param name="obj">需要序列化的对象</param>

        /// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>

        /// <returns>序列化后的字符串</returns>
        public static string XmlSerialize<T>(T obj, bool omitXmlDeclaration)
        {



            /* This property only applies to XmlWriter instances that output text content to a stream; otherwise, this setting is ignored.

            可能很多朋友遇见过 不能转换成Xml不能反序列化成为UTF8XML声明的情况,就是这个原因。

            */

            XmlWriterSettings xmlSettings = new XmlWriterSettings();

            xmlSettings.OmitXmlDeclaration = omitXmlDeclaration;

            xmlSettings.Encoding = new System.Text.UTF8Encoding(false);

            MemoryStream stream = new MemoryStream();//var writer = new StringWriter();

            XmlWriter xmlwriter = XmlWriter.Create(stream/*writer*/, xmlSettings); //这里如果直接写成:Encoding = Encoding.UTF8 会在生成的xml中加入BOM(Byte-order Mark) 信息(Unicode 字节顺序标记) , 所以new System.Text.UTF8Encoding(false)是最佳方式,省得再做替换的麻烦

            XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

            xmlns.Add(String.Empty, String.Empty); //在XML序列化时去除默认命名空间xmlns:xsd和xmlns:xsi

            XmlSerializer ser = new XmlSerializer(typeof(T));

            ser.Serialize(xmlwriter, obj, xmlns);



            return Encoding.UTF8.GetString(stream.ToArray(), 0, stream.Capacity);//writer.ToString();

        }

        /// <summary>

        /// 使用XmlSerializer序列化对象

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <param name="path">文件路径</param>

        /// <param name="obj">需要序列化的对象</param>

        /// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>

        /// <param name="removeDefaultNamespace">是否移除默认名称空间(如果对象定义时指定了:XmlRoot(Namespace = "http://www.xxx.com/xsd")则需要传false值进来)</param>

        /// <returns>序列化后的字符串</returns>
        public static void XmlSerialize<T>(string path, T obj, bool omitXmlDeclaration, bool removeDefaultNamespace)
        {

            XmlWriterSettings xmlSetings = new XmlWriterSettings();

            xmlSetings.OmitXmlDeclaration = omitXmlDeclaration;

            using (XmlWriter xmlwriter = XmlWriter.Create(path, xmlSetings))
            {

                XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();

                if (removeDefaultNamespace)

                    xmlns.Add(String.Empty, String.Empty); //在XML序列化时去除默认命名空间xmlns:xsd和xmlns:xsi

                XmlSerializer ser = new XmlSerializer(typeof(T));

                ser.Serialize(xmlwriter, obj, xmlns);

            }

        }

        private static byte[] ShareReadFile(string filePath)
        {

            byte[] bytes;

            //避免"正由另一进程使用,因此该进程无法访问此文件"造成异常 共享锁 flieShare必须为ReadWrite,但是如果文件不存在的话,还是会出现异常,所以这里不能吃掉任何异常,但是需要考虑到这些问题 

            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {

                bytes = new byte[fs.Length];

                int numBytesToRead = (int)fs.Length;

                int numBytesRead = 0;

                while (numBytesToRead > 0)
                {

                    int n = fs.Read(bytes, numBytesRead, numBytesToRead);

                    if (n == 0)

                        break;

                    numBytesRead += n;

                    numBytesToRead -= n;

                }

            }

            return bytes;

        }

        /// <summary>

        /// 从文件读取并反序列化为对象 (解决: 多线程或多进程下读写并发问题)

        /// </summary>

        /// <typeparam name="T">返回的对象类型</typeparam>

        /// <param name="path">文件地址</param>

        /// <returns></returns>
        public static T XmlFileDeserialize<T>(string path)
        {

            byte[] bytes = ShareReadFile(path);

            if (bytes.Length < 1)//当文件正在被写入数据时,可能读出为0

                for (int i = 0; i < 5; i++)
                { //5次机会

                    bytes = ShareReadFile(path); // 采用这样诡异的做法避免独占文件和文件正在被写入时读出来的数据为0字节的问题。

                    if (bytes.Length > 0) break;

                    System.Threading.Thread.Sleep(50); //悲观情况下总共最多消耗1/4秒,读取文件

                }

            XmlDocument doc = new XmlDocument();

            doc.Load(new MemoryStream(bytes));

            if (doc.DocumentElement != null)

                return (T)new XmlSerializer(typeof(T)).Deserialize(new XmlNodeReader(doc.DocumentElement));

            return default(T);

            XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();

            xmlReaderSettings.CloseInput = true;

            using (XmlReader xmlReader = XmlReader.Create(path, xmlReaderSettings))
            {

                T obj = (T)new XmlSerializer(typeof(T)).Deserialize(xmlReader);

                return obj;

            }

        }

        /// <summary>

        /// 使用XmlSerializer反序列化对象

        /// </summary>

        /// <param name="xmlOfObject">需要反序列化的xml字符串</param>

        /// <returns>反序列化后的对象</returns>
        public static T XmlDeserialize<T>(string xmlOfObject) where T : class
        {
            XmlReader xmlReader = XmlReader.Create(new StringReader(xmlOfObject), new XmlReaderSettings());
            return (T)new XmlSerializer(typeof(T)).Deserialize(xmlReader);
        }

        #endregion


 

 

更多示例:

XML文件的读取用XmlDocument和XmlReader的比较

Javascript对XML文档的加载与查询

C# 使用XmlDocument类对XML文档进行操作

C# LINQ to XML

XML to DataTable with LINQ

http://blogs.msdn.com/b/aconrad/archive/2007/09/07/science-project.aspx

更详细的

http://www.cnblogs.com/vwxyzh/category/208514.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值