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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值