C# XML 嵌套數組的序列化方法

XML示例

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:QQQ="http://www.sss.org.cn" xmlns:WAC="http://www.aaa.com">
    <Person>
        <Name>小莫</Name>
        <Age>20</Age>
        <items>
            <QQQ:item>
                <QQQ:paraname>文化課</QQQ:paraname>
                <QQQ:paravalue>SOD1323DS</QQQ:paravalue>
            </QQQ:item>
        </items>
    </Person>
    <Person>
        <Name>小紅</Name>
        <Age>20</Age>
        <items>
            <QQQ:item>
                <QQQ:paraname>數學課</QQQ:paraname>
                <QQQ:paravalue>SID1323DSD</QQQ:paravalue>
            </QQQ:item>
            <QQQ:item>
                <QQQ:paraname>英語課</QQQ:paraname>
                <QQQ:paravalue>SID000000</QQQ:paravalue>
            </QQQ:item>
        </items>
    </Person>
</root>

其中 items是個List<item>的數組

類的代碼,這個是重點!!!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1
{
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("root", IsNullable = false)]
    public class BaseInfo
    {
        [System.Xml.Serialization.XmlElementAttribute("Person")]
        public List<Person> PersonList { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    [System.Xml.Serialization.XmlRootAttribute("Person", IsNullable = false)]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        [System.Xml.Serialization.XmlElementAttribute("items")]//標識A
        public items items { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.sss.org.cn")]//Namespace屬性不需要可以不填寫
    [System.Xml.Serialization.XmlRootAttribute("items", IsNullable = false)]
    public class items//此類名必須與節點名相同   標識A
    {
        [System.Xml.Serialization.XmlElementAttribute("item")]
        public List<Item> ItemList { get; set; }
    }

    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.sss.org.cn")]//Namespace屬性不需要可以不填寫
    [System.Xml.Serialization.XmlRootAttribute("item", IsNullable = false)]
    public class item //類名必須與節點名相同!
    {
        public string paraname { get; set; }
        public string paravalue { get; set; }
    }
}

需要注意的是  items的類名必須和XML中的元素名相同,上面代碼中 寫着 標識A 的名稱必須一致

序列化方法類

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace XmlTool
{
    public class XmlSerializeHelper
    {

        #region 使用演示
        //Request  類名
        //patientIn 實例名
        //strxml xml字符串

        //序列化演示
        //string strxml = XmlSerializeHelper.XmlSerialize<Request>(patientIn);
        //反序列化演示
        //Request r = XmlSerializeHelper.DESerializer<Request>(strxml); 
        public Dictionary<string, string> students = new Dictionary<string, string>();
        #endregion

        ///// <summary>
        ///// 實體類轉換成XML
        ///// </summary>
        ///// <typeparam name="T">類名</typeparam>
        ///// <param name="obj">T類名的實例</param>
        ///// <returns></returns>
        //public static string XmlSerialize<T>(T obj)
        //{
        //    using (StringWriter sw = new StringWriter())
        //    {
        //        Type t = obj.GetType();
        //        XmlSerializer serializer = new XmlSerializer(obj.GetType());
        //        serializer.Serialize(sw, obj);
        //        sw.Close();
        //        return sw.ToString();
        //    }
        //}

        /// <summary>
        /// 將一個對象序列化爲XML字符串
        /// </summary>
        /// <param name="o">要序列化的對象</param>
        /// <param name="encoding">編碼方式</param>
        /// <param name="DicPrefix">需要指定的前綴對應,格式爲 key爲命名空間,value爲前綴</param>
        /// <returns>序列化產生的XML字符串</returns>
        public static string XmlSerialize(object o, Encoding encoding, Dictionary<string, string> DicPrefix)
        {
            if (o == null)
                throw new ArgumentNullException("o");
            if (encoding == null)
                throw new ArgumentNullException("encoding");

            string xml = "";
            try
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.Encoding = encoding;

                    //OmitXmlDeclaration表示不生成聲明頭,默認是false,OmitXmlDeclaration爲true,會去掉<?xml version="1.0" encoding="UTF-8"?>
                    //settings.OmitXmlDeclaration = true;

                    XmlWriter writer = XmlWriter.Create(stream, settings);

                    #region 指定命名空間前綴的方法
                    //強制指定命名空間,覆蓋默認的命名空間,可以添加多個,如果要在xml節點上添加指定的前綴,可以在跟節點的類上面添加[XmlRoot(Namespace = "http://www.w3.org/2001/XMLSchema-instance", IsNullable = false)],Namespace指定哪個值,xml節點添加的前綴就是哪個命名空間(這裏會添加ceb)
                    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                    if (DicPrefix!=null)
                    {
                        NamespacesSpecifiedPrefix(namespaces, DicPrefix);
                    }
                    
                    //namespaces.Add(參數1, 參數2);
                    //解讀:"參數1"爲要使用的前綴,對應類中使用"參數2"的命名空間的節點
                    #endregion

                    XmlSerializer serializer = new XmlSerializer(o.GetType());
                    serializer.Serialize(writer, o, namespaces);
                    writer.Close();

                    stream.Position = 0;
                    using (StreamReader reader = new StreamReader(stream, encoding))
                    {
                        xml = reader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {

            }
            return xml;
        }
        /// <summary>
        /// 指定修改的前綴,遍歷字典添加
        /// </summary>
        /// <param name="namespaces">要添加命名空間的對象</param>
        /// <param name="DicPrefix">包含命名空間和前綴的字典</param>
        private static void NamespacesSpecifiedPrefix(XmlSerializerNamespaces namespaces, Dictionary<string, string> DicPrefix)
        {
            foreach (KeyValuePair<string, string> kvp in DicPrefix)
            {
                namespaces.Add(kvp.Value, kvp.Key);
            }
        }




        /// <summary>
        /// XML轉換成實體類-方法1
        /// </summary>
        /// <typeparam name="T">對應的類</typeparam>
        /// <param name="strXML">XML字符串</param>
        /// <returns></returns>
        public static T DESerializer<T>(string strXML) where T : class
        {
            try
            {
                using (StringReader sr = new StringReader(strXML))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// XML轉換成實體類-方法2
        /// </summary>
        /// <param name="xmlStr"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object DeserializeFromXml(string xmlStr, Type type)
        {
            try
            {
                using (StringReader sr = new StringReader(xmlStr))
                {
                    XmlSerializer xs = new XmlSerializer(type);
                    return xs.Deserialize(sr);
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }
        //Request
        //


    }
}

使用方法

private static void aaa()
{
    BaseInfo baseInfo = new BaseInfo();
    List<Person> personList = new List<Person>();
    Person p1 = new Person();
    p1.Name = "小莫";
    p1.Age = 20;

    List<Item> books = new List<Item>();
    Item book = new Item();
    book.paraname = "文化課";
    book.paravalue = "SOD1323DS";
    books.Add(book);
    p1.items = new items();
    p1.items.ItemList = books;

    Person p2 = new Person();
    p2.Name = "小紅";
    p2.Age = 20;

    List<Item> books2 = new List<Item>();
    Item book2 = new Item();
    book2.paraname = "數學課";
    book2.paravalue = "SID1323DSD";
    books2.Add(book2);
    Item book3 = new Item();
    book3.paraname = "英語課";
    book3.paravalue = "SID000000";
    books2.Add(book3);
    p2.items = new items();
    p2.items.ItemList = books2;

    personList.Add(p1);
    personList.Add(p2);


    baseInfo.PersonList = personList;

    //類轉XML,帶前綴
    string postXml4 = XmlSerializeHelper.XmlSerialize(baseInfo, Encoding.UTF8, new Dictionary<string, string>() { { "http://www.aaa.com", "WAC" }, { "http://www.sss.org.cn", "QQQ" } });
    //XML轉XML
    BaseInfo BL = (BaseInfo)XmlSerializeHelper.DeserializeFromXml(postXml2, typeof(BaseInfo));//XML轉類

    Console.ReadLine();
}

以上

小技巧:當對應XML的類很複雜,序列化又出錯的時候,可以分模塊,單獨提出一個節點元素與對應的一個小類進行序列化測試

例如:單獨將Item拿出來進行反序列化,但一定注意最外層不能有前綴,且如果XML中使用了前綴,一定要帶命名空間xmlns

  <item xmlns:QQQ="http://www.sss.org.cn">
    <QQQ:paraname>數學課</QQQ:paraname>
    <QQQ:paravalue>SID1323DSD</QQQ:paravalue>
  </item>
string fff = System.IO.File.ReadAllText("./XMLFile3.xml");
Item bk = (Item)XmlSerializeHelper.DeserializeFromXml(fff, typeof(Item));//轉爲Item類

即可用這種方法分步進行測試以找出序列化錯誤的地方

學習資料來自:https://www.cnblogs.com/mq0036/p/12049881.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章