C#——XML序列化

news2024/11/25 0:06:02

开发环境

VS2022

.net core 6.0

序列化概念

序列化是将内存中的对象或者对象图(一组相互引用的对象)拉平为一个可以保存或进行传输的字节流,或者XML节点。反序列化正好相反,它把数据流重新构造成内存中的一个对象或者对象图。

序列化用途

序列化和反序列化通常用于:

· 通过网络或程序边界传输对象

· 在文件或者数据库中保存对象

此外,它还可以用于深度克隆对象。而数据契约和XML序列化引擎也可以当作通用工具,用于加载和保存已知结构的XML文件。

可序列化的项

  • 公共类的公共读/写属性和字段。

  • 执行 ICollection 或 IEnumerable 的类 。

  • XmlElement 对象。

  • XmlNode 对象。

  • DataSet 对象。

序列化常用特性

XmlRoot——申明根结点,如: [XmlRoot(ElementName = "Root")]

XmlIgnore——忽悠某个属性或字段,如 :[XmlIgnore] public int Id;

XmlInclude——是否包含某个类,如:[XmlInclude(typeof(Results))]

XmlArray——申明集合

XmlArrayItem——申明集合中元素,如下:

        [XmlArray("Targets", Namespace = "TwoPoint")]
        [XmlArrayItem("Target", Namespace = "TwoPoint")]
        public Point[] Points { get; set; }

XML 序列化注意事项

使用 XmlSerializer 类时,应注意以下事项:

  • 序列化数据只包含数据本身和类的结构。 

  • 只能序列化公共属性和字段。 属性必须具有公共访问器(get 和 set 方法)。 

  • 类必须具有无参数构造函数才能被 XmlSerializer 序列化。

  • 方法不能被序列化。

  • 如下所述,如果实现 IEnumerable 或 ICollection 的类满足某些要求,XmlSerializer 则可以处理这些类 。

    实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法 。

    实现 ICollection 的类(如 CollectionBase)必须具有采用整型的公共“Item”索引属性(在 C# 中为索引器),而且它必须有一个“integer”类型的公共“Count”属性 。 传递给 Add 方法的参数必须与从“Item”属性返回的类型相同,或者为此类型的基之一 。

常见错误及解决办法

以下为愚初次使用时遇到的一引问题,及解决办法:

 不同命名空间下的相同类名下异常

InvalidOperationException: Types 'WpfApp.Xml.Results.Target' and 'WpfApp.Xml.PlanInfo.Target' both use the XML type name, 'Target', from namespace ''. Use XML attributes to specify a unique XML name and/or namespace for the type.

解决办法:如上黄色字体,即为序列化的对象添加Namespace,如下

    [XmlType(Namespace = "WpfApp.Xml.Results")]
    public class Target
    {
        /// <summary>
        /// 编号
        /// </summary>
        [XmlAttributeAttribute(AttributeName = "id")]
        public double NO { get; set; }

    }

注意仅需要添加Namespace即可,不需要添加TypeName。

很多文章提到应该添加TypeName和Namespace,如下的操作方式:

    [XmlType(TypeName = "PTarget", Namespace = "WpfApp.Xml.Info")]
    public class Target
    {
        /// <summary>
        /// 编号
        /// </summary>
        [XmlAttributeAttribute(AttributeName = "id")]
        public double NO { get; set; }

    }

但若添加了TypeName会导致你后一个不同NameSpace下的类改为你Namespace中设置的名称。

非集合属性或字段添加了集合特性

InvalidOperationException: For non-array types, you may use the following attributes: XmlAttribute, XmlText, XmlElement, or XmlAnyElement.

集合属性或字段添加了 XmlElement

集合不能使用它,否则会导致它的子元素全部显示为Targets,而应该如下:

        [XmlArray("Targets")]
        [XmlArrayItem("Target")]
        public Point[] Points { get; set; }

XmlArray指定了集合Points在Xml中的显示名称,

XmlArrayItem指定了集合中元素在Xml中的显示名称。

对象序列化与反序列化常用代码

对象序列化为XML文件

        /// <summary>
        /// 序列化对象为XML文件
        /// </summary>
        internal static void XmlSerializer<T>(string fileName, T t) where T : new()
        {

            try
            {

                XmlSerializer serializer = new(typeof(SerializationWrapper));
                using TextWriter tr = new StreamWriter(fileName, false, Encoding.UTF8);
                // 序列化包装类
                serializer.Serialize(tr, t);
                tr.Close();
                tr.Dispose();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("序列化失败");
                Exception exception = new("序列化失败");
                throw exception;
            }
        }

xml文件反序化为对象

        /// <summary>
        /// 反序列化XML文件为对象
        /// </summary>
        /// <param name="fileName">文件名</param
        internal static T XmlDeserialize<T>(string fileName) where T : new()  
        {
            using FileStream s = File.OpenRead(fileName);

            // 创建包装类的实例并添加对象
            XmlSerializer xs = new(typeof(T));
            T sw = (T)xs.Deserialize(s);
            return sw;
        }

上述代码最好还是添加上try……catch……以进行错误处理。

对象序列化为字符串

        /// <summary>
        /// 将对象序列化为XML字符串
        /// </summary>
        /// <typeparam name="T">需要序列化的类型</typeparam>
        /// <param name="t">序列化的对象实例</param>
        /// <returns>序列化对象的字符串</returns>
        internal static string Object2XmlStringSerializer<T>(T t) where T : new()
        {
            try
            {
                // 创建包装类的实例并添加对象
                T wrapper = t;
                // 创建XmlSerializer的实例,指定根元素名称
                XmlSerializer serializer = new(typeof(T));

                // 使用StringWriter来捕获序列化后的XML内容
                using (StringWriter stringWriter = new())
                {
                    serializer.Serialize(stringWriter, wrapper);
                    string xmlContent = stringWriter.ToString();
                    Debug.WriteLine(xmlContent);
                    return xmlContent;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("序列化失败");
                Exception exception = new("序列化失败");
                throw exception;
            }
        }

xml字符串反序化为对象

/// <summary>
/// 将XML字符串反序列化为对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xmlString"></param>
/// <returns></returns>
internal static T XmlStringDeserializer<T>(string xmlString) where T : Results, new()
{
    // 使用StringReader包装XML字符串
    using StringReader stringReader = new(xmlString);
    try
    {
        XmlSerializer serializer = new(typeof(T));
        // 反序列化XML字符串
        T root = (T)serializer.Deserialize(stringReader);
        return root;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

参考资料

《C# 核心技术指南(原书第7版)》

XML 序列化详细信息 - .NET | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【位运算】--- 进阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Journey 本节我们来赏析位运算的一些进阶题目。 &#x1f3e0; 只出现一次的数字II &#x1f4cc; 题目解析 只出现一次的数字II &#x1f4cc; 算…

Anylogic制作界面元素tips

点击元素后跳转至其他视图&#xff0c;且能够把某个共同元素移植过去 navigate( viewStatistics2 ); groupControls.setX( groupControls.getX() 1200 );

python-笨小猴

题目描述 笨小猴的词汇量很小&#xff0c;所以每次做英语选择题的时候都很头疼。但是他找到了一种方法&#xff0c;经试验证明&#xff0c;用这种方法去选择选项的时候选对的几率非常大&#xff01; 这种方法的具体描述如下&#xff1a;假设maxn是单词中出现次数最多的字母的出…

kafka3.7.1 单节点 KRaft部署测试发送和接收消息

一、环境准备 kafka3.7.1 包下载地址&#xff1a; https://mirrors.nju.edu.cn/apache/kafka/3.7.1/kafka_2.13-3.7.1.tgz openjdk11.0.2 下载地址&#xff1a; https://mirrors.nju.edu.cn/openjdk/11.0.2/openjdk-11.0.2_linux-x64_bin.tar.gz 二、openjdk 安装 【如已安装…

设计模式学习-简单的命令模式例子

上一章节介绍过了命令模式&#xff0c;这一篇文章就简单的做一个小案例来巩固学习 搭建场景 简单的搭建一个场景就行 &#xff0c;随便准备一个物体放在场景中位置Reset一下即可。 代码编写 定义接口&#xff08;或者抽象类&#xff09;ICommand 用来规范Command的行为。注意…

在线音乐播放器项目

在线音乐播放器项目 登录页面 注册页面 主页 上传文件 我的喜欢 前端 js html css 三剑客 后端 Spring Boot框架 插件有:Spring Boot DevTools、Lombok、Spring Web、MySQL Driver、MyBatis Framework、security、detect 数据库有 三张表 lovemusic、music、user 工具类( co…

pycharm的Structure是什么,怎么打开,每个图标的功能是什么

一、Structure的含义 在PyCharm中&#xff0c;Structure是一个非常有用的功能&#xff0c;它可以帮助开发者快速浏览和理解当前文件的代码结构&#xff0c;Structure视图通过不同的图标来表示代码中的不同元素。 二、如何打开Structure功能 在windows上可以通过Alt7来打开St…

VsCode + Go + macOS 小白 demo运行

1. 安装&#xff1a;brew install go 2. 设置工作目录和代理 ​ go env -w GOPATH/Users/niu/code/goexport GOPROXYhttps://goproxy.cngo env -w GO111MODULEongo env 查看上面三个值是否和设置的一样​ 3. 安装vscode. go插件 4. vscode打开GOPATH设置的工作目录 command…

ESP32无线WiFi芯片模组,设备物联网连接通信,产品智能化交互升级

在数字化浪潮的推动下&#xff0c;我们正步入一个万物互联的新时代。物联网&#xff08;IoT&#xff09;技术&#xff0c;作为连接物理世界与数字世界的桥梁&#xff0c;正逐渐渗透到我们生活的每一个角落。 乐鑫正通过其创新的无线WiFi芯片模组&#xff0c;为这些领域的发展提…

Linux动态监控系统

目录 动态监控进程 介绍 基本语法 选项说明 交互操作说明 应用实例 动态监控进程 介绍 top指令类似于ps命令&#xff0c;只是top在执行一段时间可以更新正在运行的进程。 基本语法 选项说明 负载那三个值加起来除以三若大于零点7就说明负载较大 &#xff0c;buff是占用…

全网最全的安服工程师修炼手册

全网最全安服工程师修炼手册 本篇文章主要介绍安全服务工程师的必备技能&#xff0c;也是简单记录下我的安服历程&#xff01; 思维导图附上 点击下载 基础技能 网络 IP IP概念&#xff1a;IP地址被用来给Internet上的电脑一个编号。日常见到的情况是每台联网的PC上都需要…

Faiss向量数据库

Faiss&#xff08;Facebook AI Similarity Search&#xff09;向量数据库是由Facebook AI研究院开发的一种高效相似性搜索和聚类的库。Faiss不仅支持在高维空间中进行高效的相似性搜索&#xff0c;还能够在处理大规模数据集时展现出卓越的性能&#xff0c;尤其适用于图像检索、…

C# SM2 SM3 SM4 使用

目录 效果 SM2 SM3 SM4 项目 代码 SM2Utils.cs Sm3Utils.cs Sm4Utils.cs 下载 效果 SM2 公钥&#xff1a;04ca3e272e11b5633681cb0fbbfd8c162be08918ce5b644cd33d49c17be8674caf6c20a11de8b65333924dfe7d42246abb4a4c36b663bef1aafc624a35acf4d2b1 私钥&#xff1a;…

多个视频怎么合成一个视频?这10款视频合并软件大家都在用,适合手机和电脑!

如果您希望利用拍摄的片段制作出色的电影或视频故事&#xff0c;选择合适的视频合并软件是非常关键的。此外&#xff0c;视频剪辑的复杂程度可能会让人感到意外&#xff0c;有时简单得让人吃惊。专业的视频剪辑合并大师能够大大简化视频合并的过程&#xff0c;这正是它们的价值…

『功能项目』主角的信息显示【16】

本章项目成果展示 我们打开上一篇15怪物的信息显示的项目&#xff0c; 本章要做的事情是对主角的UI信息实时显示 创建一个脚本&#xff1a;UIManager.cs 创建一个空物体作为钉子钉在左上角命名为LeftUp 创建Image做为头像 将以下资源导入Art文件夹 将以下资源图片放至Art文件夹…

思维导图软件全攻略:5款软件横向对比

思维导图作为一种图形化的工具&#xff0c;能够帮助我们更有效地组织和表达放射性思维。在学习和工作中&#xff0c;思维导图的作用不可小觑&#xff0c;它不仅帮助我们理清思路&#xff0c;还能提升我们的工作效率。通过可视化的方式&#xff0c;思维导图将复杂的信息分解成更…

JDK原理

当我们谈论JDK&#xff08;Java Development Kit&#xff09;的原理时&#xff0c;实际上是在探讨Java语言及其开发环境背后的技术和设计思想。JDK是Java编程语言的核心工具包&#xff0c;它包含了Java运行环境&#xff08;JRE&#xff09;、Java编译器&#xff08;javac&#…

U盘数据恢复哪家强?四款神器拯救你的文件!

随着科技的发展&#xff0c;我们越来越依赖于电子设备来储存和传输数据。然而&#xff0c;数据丢失的情况也时有发生&#xff0c;尤其是当我们的数据存储在U盘等移动设备上时。这时&#xff0c;U盘数据恢复软件就显得尤为重要了。本文将为大家介绍四款常用的U盘数据恢复软件&am…

按箭头上下左右来实现简单二层级树形结构

按箭头上下左右来实现简单二层级树形结构 .vue template内容 <div class"nav-container"><ul class"nav-list" :class"{ border-glow: status F }"><liv-for"(item, index) in items":key"index"click&…

iOS 18降级后遭遇“白苹果”?可试试这几种解决办法

随着苹果iOS系统的不断升级&#xff0c;用户们总是满怀期待地尝试最新的系统版本&#xff0c;但偶尔也会因为某些原因选择降级回旧版本。然而&#xff0c;iOS 18降级后遇到“白苹果”问题&#xff0c;无疑给许多用户带来了困扰。今天&#xff0c;我们就来探讨一下&#xff0c;当…