所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

手把手教你利用XMLSerializer将对象串行化到XML

手把手教你利用XMLSerializer将对象串行化到XML 一

文章目录CloseOpen

这篇文章会手把手带你从0到1掌握全过程:先帮你理清“对象→XML”的核心逻辑,再一步步教你定义可序列化的对象类、配置序列化规则(比如自定义XML元素名称、忽略空属性)、编写代码实现序列化,甚至避开“循环引用”“类型不支持”等常见坑。不管你是要存储配置数据,还是和老系统做接口交互,跟着文中的步骤操作,就能快速得到符合要求的XML文档,再也不用为这个需求挠头啦。

你有没有过这种情况?领导让你把系统里的用户对象转成XML格式存起来,或者对接老系统的XML接口,你盯着代码框半天,要么搞不清“序列化”到底是啥,要么写出来的XML要么少字段,要么格式乱得没法看?我去年帮做物流系统的朋友解决过一模一样的问题——当时他对着“找不到类型”的报错信息急得直挠头,后来用XMLSerializer一步步拆解,不到半天就搞定了。其实这工具没你想的那么复杂,今天我把亲测有效的步骤拆成“说人话”的版本,你跟着做就能直接用。

先搞懂:XMLSerializer到底能帮你解决什么问题

先别急着写代码,我先跟你掰扯明白核心逻辑——对象串行化到XML 其实就是“把程序里的对象(比如一个包含姓名、年龄、地址的用户信息),转换成结构化的XML文本”。打个比方:你要把衣柜里的衣服寄给朋友,得先把衣服叠成统一形状(序列化),才能装进标准尺寸的箱子(存储/传输);而XMLSerializer就是.NET框架里专门干“叠衣服”的工具——它能自动把对象的属性对应到XML的标签里,不用你手动拼字符串(我之前试过手动拼XML,光处理< &这些特殊字符就花了两小时,还漏了个字段,被测试同学骂得狗血淋头)。

那为啥非要用XMLSerializer?两个关键原因:

  • 适配老系统:很多工业设备(比如仓库控制器)、传统ERP系统只认XML格式,Json根本不好使——我朋友的物流系统对接的仓库管理系统就是这样,必须传XML;
  • 省心省力:它是.NET自带的,不用额外装NuGet包(省得解决版本冲突),而且微软官方文档明确说过,“XMLSerializer适合处理需要严格结构的XML数据”(链接:)。
  • 简单说:只要你需要把对象转XML,XMLSerializer就是性价比最高的选择——我至今没遇到过它搞不定的基础场景。

    手把手操作:从0到1实现对象到XML的序列化

    接下来进入正题,我把步骤拆成“能直接抄的代码+能听懂的解释”,你跟着做就行。

    第一步:定义“可被序列化”的对象类

    要让XMLSerializer“认识”你的对象,得先给对象“贴标签”——不是让你写备注,是用.NET的特性(Attribute) 告诉工具:“这个属性要生成什么标签?要不要忽略?”

    先看个例子,比如你要序列化“用户”对象,类可以这么写:

    using System.Xml.Serialization; // 必须引入这个命名空间!
    

    public class User

    {

    // 把Name属性的XML标签改成(默认是)

    [XmlElement("UserName")]

    public string Name { get; set; }

    // 把Age属性变成标签的属性(默认是子标签)

    [XmlAttribute("UserAge")]

    public int Age { get; set; }

    // 普通属性,默认生成

    子标签

    public string Address { get; set; }

    // 忽略这个属性,不生成到XML里

    [XmlIgnore]

    public DateTime CreateTime { get; set; }

    }

    我帮你把常用的特性整理成了表格,一目了然:

    特性名称 作用 实战例子
    [XmlElement] 自定义XML子标签的名称 想把改成,就加这个
    [XmlAttribute] 把属性变成根标签的属性(不是子标签) Age变成里的属性
    [XmlIgnore] 忽略该属性,不生成到XML CreateTime不需要传,就加这个

    划重点:对象的属性必须是public(公共的)——我朋友当时犯了个低级错误:把Address设成了private,结果XML里少了地址字段,被仓库系统打回三次才发现。

    第二步:写代码——四步生成符合要求的XML

    接下来是最核心的代码环节,其实就4步,我帮你拆得明明白白:

  • 引用必要的命名空间
  • 先在代码顶部加两行:

    using System.Xml.Serialization; // 处理XML序列化
    

    using System.IO; // 处理文件流/字符串流

  • 新建XMLSerializer实例
  • 你得告诉工具“我要序列化什么类型的对象”——比如要序列化User类,就写:

    var serializer = new XmlSerializer(typeof(User));

    这里的typeof(User)就是“目标类型是User”,相当于你跟快递员说“我要寄的是衣服”。

  • 准备要序列化的对象
  • 就是你要转成XML的“原始数据”——比如:

    var user = new User
    

    {

    Name = "张三",

    Age = 30,

    Address = "北京市朝阳区",

    CreateTime = DateTime.Now // 这个会被[XmlIgnore]忽略

    };

  • 选择“输出方式”并执行序列化
  • XMLSerializer支持写文件存字符串传网络流三种常见场景,我分别给你举例子:

    场景1:生成XML文件(存本地/服务器)

    如果要把XML存成文件(比如我朋友的物流系统要存订单日志),用FileStream

    // 用using包裹,自动释放资源(避免文件被占用)
    

    using (var stream = new FileStream("user.xml", FileMode.Create))

    {

    serializer.Serialize(stream, user); // 执行序列化

    }

    运行后,打开user.xml会看到:

    
    
    

    张三

    北京市朝阳区

    是不是和你想的一样?Name变成了Age变成了根标签的属性,CreateTime直接消失了——这就是特性的作用!

    场景2:生成XML字符串(对接接口)

    如果要把XML传给接口(比如调用老系统的API),用StringWriter

    using (var writer = new StringWriter())
    

    {

    serializer.Serialize(writer, user);

    string xmlString = writer.ToString(); // 得到XML字符串

    Console.WriteLine(xmlString); // 输出看看结果

    }

    这样你就能直接把xmlString作为接口参数传出去——我上周对接一个政府系统的XML接口,就是用这方法,一次就过了。

    第三步:避坑指南——我踩过的雷,你别再踩

    别以为这样就完了,我再跟你说几个高频踩坑点,都是我和朋友亲身经历的:

    坑1:循环引用报错

    比如你的User类里有个Order属性(订单),Order类里又有个User属性(用户)——这就形成了“循环引用”,XMLSerializer会直接报错“无法序列化循环引用”。

    解决办法:在其中一个属性上加[XmlIgnore]——我朋友的物流系统里有“订单-用户”的循环,后来把Order里的User加了[XmlIgnore],问题解决。

    坑2:不支持字典(Dictionary)类型

    XMLSerializer默认不支持Dictionary(比如Dictionary),会报“无法序列化非公共类型”。

    解决办法:把字典转成List>——我之前要序列化“配置项”字典,转成List后完美解决。

    坑3:需要特定命名空间

    有些系统要求XML必须带命名空间(比如xmlns="http://www.example.com"),这时候可以在新建XmlSerializer时指定:

    // 第二个参数是命名空间
    

    var serializer = new XmlSerializer(typeof(User), "http://www.example.com");

    生成的XML根标签会变成:

    再升级:让你的XML更“听话”——自定义序列化规则

    如果你想让XML更贴合业务需求(比如改根标签名称、调整元素顺序),XMLSerializer也能搞定,我再教你两个实用技巧:

    技巧1:修改根标签的名称

    默认情况下,根标签名称是类名(比如User类对应),如果想改成,只需在类上加[XmlRoot]特性:

    [XmlRoot("Customer")] // 根标签改成
    

    public class User

    {

    // 其他属性不变

    }

    生成的XML根标签就会变成——我朋友后来对接另一个系统时,就是用这招改了根标签,直接通过审核。

    技巧2:调整元素的顺序

    如果系统要求XML元素按“Age→Name→Address”的顺序排列,只需给[XmlElement]Order参数:

    public class User
    

    {

    [XmlElement("UserName", Order = 2)] // 第2个出现

    public string Name { get; set; }

    [XmlAttribute("UserAge")]

    public int Age { get; set; }

    [XmlElement(Order = 1)] // 第1个出现

    public string Address { get; set; }

    }

    生成的XML会变成:

    
    
    

    北京市朝阳区

    张三

    是不是刚好符合顺序要求?

    最后:试一次——你一定能成

    怎么样?是不是比你想的简单多了?我去年帮朋友做的时候,一开始也怕“写错代码”,后来把步骤拆成“先定义类→再写 serializer→最后选输出方式”,反而越做越顺。

    你可以先复制我给的代码,把User改成你业务里的类(比如OrderProduct),改改属性和特性,试试生成XML——如果遇到问题(比如报错“无法序列化”,或者格式不对),欢迎回来跟我说,我帮你看看。

    对了,如果你按这个方法试了,记得在评论区告诉我效果——我去年帮朋友搞定后,他请我吃了顿火锅;你要是成了,也可以跟我分享你的“小成就”呀~


    XMLSerializer到底适合什么时候用啊?

    其实它最适合两种场景:一是对接只认XML的老系统,比如工业设备、传统ERP或者仓库管理系统,这些地方Json根本不好使;二是需要严格结构化的XML数据,比如要存配置文件或者日志,它能自动把对象转成标准XML,不用你手动拼字符串。而且它是.NET自带的,不用额外装NuGet包,省得解决版本冲突,微软官方也说它适合处理这种需求。

    为什么我定义的对象类序列化后少了字段?

    首先得检查你那字段是不是public的——XMLSerializer只认公共属性,要是设成private或者protected,肯定不会生成到XML里,我之前帮朋友调bug就遇到过这情况,他把Address设成private,结果XML里少了地址字段。另外看看是不是加了XmlIgnore特性,这个特性会直接忽略对应的字段,要是不小心加错了也会少字段。

    序列化时遇到循环引用报错怎么办?

    循环引用就是两个对象互相引用,比如User类里有个Order属性,Order类里又有个User属性,XMLSerializer没法处理这种“套娃”情况,会直接报错。解决办法也简单,在其中一个属性上加XmlIgnore特性就行,比如把Order里的User属性忽略掉,这样就不会循环了,我朋友的物流系统对接时就用这招解决了。

    想改XML根标签的名称怎么操作?

    直接在你要序列化的类上加XmlRoot特性就行,比如你有个User类,想让根标签变成,就在类上面写[XmlRoot(“Customer”)],这样生成的XML根标签就会从改成了,我朋友后来对接另一个系统时就用这方法改了根标签,直接通过审核。

    怎么调整XML里元素的顺序?

    用XmlElement特性的Order参数就行,比如你想让Address字段在UserName前面出现,就给Address的XmlElement加Order=1,UserName的加Order=2,这样生成的XML里Address就会排在前面。比如文章里的例子,设置Order后,Address先出现,UserName跟着,刚好符合系统要求的顺序。

    原文链接:https://www.mayiym.com/50209.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码