当前位置: 首页 > news >正文

Dotnet使用System.Xml.Serialization处理Xml序列化

image.png

命名空间

作为一种归纳方式,便于后续命名空间的快速引入。

 /// <summary>/// 定义 命名空间常量/// </summary>public static class WpmlNamespace{public const string Wpml = "http://www.dji.com/wpmz/1.0.2";public const string Kml = "http://www.opengis.net/kml/2.2";}

根节点

使用[XmlRoot] 、自定义根节点属性[XmlAttribute]以及配置子节点[XmlElement]

    [XmlRoot("kml", Namespace = WpmlNamespace.Kml)]public class KmlRoot{[XmlElement("Document", Namespace = WpmlNamespace.Kml)]public Document Document { get; set; }[XmlAttribute("wpml", Namespace = "http://www.w3.org/2000/xmlns/")]public string WpmlNamespaceAttribute { get; set; } = WpmlNamespace.Wpml;}

子节点类型

使用[XmlElement] 特性,进行子节点序列名称以及对应的命名空间。

//[XmlType("Document", Namespace = WpmlNamespace.Kml)]
public class Document
{// 创建信息 (Document的子元素)[XmlElement("author", Namespace = WpmlNamespace.Wpml)]public string Author { get; set; } // 非必需[XmlElement("createTime", Namespace = WpmlNamespace.Wpml)]public long? CreateTime { get; set; } // 非必需, ms 时间戳[XmlElement("updateTime", Namespace = WpmlNamespace.Wpml)]public long? UpdateTime { get; set; } // 非必需, ms 时间戳
}

填充数据

逐步构建实例数据,用于后续查看序列化效果。

// 创建KML内容的逻辑
KmlRoot kmlRoot = new KmlRoot();
// Document 节点
Document document = new Document();
kmlRoot.Document = document;
document.CreateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
document.UpdateTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

序列化输出

使用XmlSerializerXmlWriterSettingsStringWriter以及XmlWriter生成序列数据。

// 构建序列化实例
var serializer = new XmlSerializer(typeof(KmlRoot), null,null, null,null);
var settings = new XmlWriterSettings // 序列化配置
{Indent = true, // 启用自定义间隔IndentChars = "  ",// 属性间隔Encoding = Encoding.UTF8,// 设置编码格式OmitXmlDeclaration = false, // 保持 XML 声明
};
using (var stringWriter = new System.IO.StringWriter())
using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
{// 序列化对象serializer.Serialize(xmlWriter, kmlRoot);// 获取序列化后的字符串var xmlString = stringWriter.ToString();return xmlString;
}

序列化结果如下:

<?xml version="1.0" encoding="utf-16"?>
<kml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2"><Document><wpml:createTime>1761753196268</wpml:createTime><wpml:updateTime>1761753196269</wpml:updateTime></Document>
</kml>

修改xml声明

可以看到序列化输出结果中,当前文本的文本编码说明为UTF-16,实际需要的是UTF-8,原始文本编码和目标编码如下。
原始文本编码。

<?xml version="1.0" encoding="utf-16"?>

目标文本编码。

<?xml version="1.0" encoding="utf-8"?>

解决办法是继承StringWriter 类,重写编码属性。

// 设置文本编码为utf-8
public class Utf8StringWriter: System.IO.StringWriter
{public override Encoding Encoding => Encoding.UTF8;
}

替换序列化代码中的StringWriter 实例构造。

//using (var stringWriter = new StringWriter())
using (var stringWriter = new Utf8StringWriter())
using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
{// 序列化对象serializer.Serialize(xmlWriter, kmlRoot);// 获取序列化后的字符串var xmlString = stringWriter.ToString();return xmlString;
}

输出结果如下:

<?xml version="1.0" encoding="utf-8"?>
<kml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2"><Document><wpml:createTime>1761753196268</wpml:createTime><wpml:updateTime>1761753196269</wpml:updateTime></Document>
</kml>

xml大写声明编码值

当前小写编码值:

<?xml version="1.0" encoding="utf-8"?>

期望大写编码值:

<?xml version="1.0" encoding="UTF-8"?>

自定义UTF8Encoding编码类。

/// <summary>
/// 自定义大写的 UTF8Encoding
/// </summary>
public class CustomUTF8Encoding : UTF8Encoding
{public override string HeaderName => base.HeaderName.ToUpper();public override string WebName => base.WebName.ToUpper();public override string BodyName => base.BodyName.ToUpper();
}

修改Utf8StringWriter类代码。

public class Utf8StringWriter: System.IO.StringWriter
{public Utf8StringWriter(){}public override Encoding Encoding => new CustomUTF8Encoding();
}

不显示默认值属性

对于未赋值字段,默认会显示并标记为xsi:nil="true",这在某些场景并不合适,需要进行去除。

<?xml version="1.0" encoding="utf-8"?>
<kml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2"><Document><wpml:createTime>1761899701431</wpml:createTime><wpml:updateTime>1761899701431</wpml:updateTime><wpml:missionConfig><wpml:executeRCLostAction xsi:nil="true" /><wpml:takeOffSecurityHeight>0</wpml:takeOffSecurityHeight><wpml:takeOffRefPointAGLHeight xsi:nil="true" /><wpml:globalTransitionalSpeed>0</wpml:globalTransitionalSpeed><wpml:globalRTHHeight xsi:nil="true" /></wpml:missionConfig></Document>
</kml>

对应属性修改为完整属性。

        private double? takeOffRefPointAGLHeight;[XmlElement("takeOffRefPointAGLHeight", Namespace = WpmlNamespace.Wpml)]public double? TakeOffRefPointAGLHeight { get => takeOffRefPointAGLHeight; set => takeOffRefPointAGLHeight = value; } // 非必需, m

添加函数public bool ShouldSerialize[对应的属性名称](),此处属性为TakeOffRefPointAGLHeight对应函数如下。函数内部实际按照需求进行判定,返回false则表示序列化中不显示,反之亦然。

        public bool ShouldSerializeTakeOffRefPointAGLHeight()  => takeOffRefPointAGLHeight.HasValue;

去除自带命名空间

去除默认xml 中命名空间,如:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"以及 xmlns:xsd="http://www.w3.org/2001/XMLSchema"

<kml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2">
</kml>

期望输出:

<kml xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2">
</kml>

可以尝试使用XmlSerializerNamespaces 序列化时,进行命名空间置空。

//using (var stringWriter = new StringWriter())
using (var stringWriter = new Utf8StringWriter())
using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
{var namespaces = new XmlSerializerNamespaces();namespaces.Add("", ""); // 添加空命名空间// 序列化对象serializer.Serialize(xmlWriter, kmlRoot,namespaces);// 获取序列化后的字符串var xmlString = stringWriter.ToString();return xmlString;
}

序列化如下:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns:wpml="http://www.dji.com/wpmz/1.0.2" xmlns="http://www.opengis.net/kml/2.2"><Document></Document>
</kml>

节点子类替换父类

使用过程中,多类型嵌套时,部分节点存在之类,需要在序列化时进行替换,此时需要引入XmlAttributeOverrides,在构造序列化实例时进行类型重写。
父类类型。

public class ActionActuatorFuncParam
{}

子类类型。

public class OrientedShoot : ActionActuatorFuncParam
{[XmlElement("focusX", Namespace = WpmlNamespace.Wpml)]public int FocusX { get; set; } // 必需
}public class GimbalRotate : ActionActuatorFuncParam
{}

实际使用类。

// KML 根元素
[XmlRoot("kml", Namespace = WpmlNamespace.Kml)]
public class KmlRoot
{[XmlElement("Document", Namespace = WpmlNamespace.Kml)]public Document Document { get; set; }
}// 省略n级别嵌套类[XmlType("action", Namespace = WpmlNamespace.Wpml)]
public class WpmlAction
{[XmlElement("actionActuatorFuncParam", Namespace = WpmlNamespace.Wpml)]public WpmlActionActuatorFuncParam ActionActuatorFuncParam { get; set; }
}

数据赋值。

KmlRoot kmlRoot = new KmlRoot();
// 省略中间赋值
OrientedShoot actionActuatorFuncParam = new OrientedShoot();
action.ActionActuatorFuncParam = actionActuatorFuncParam;
actionActuatorFuncParam.FocusX = 12;// 进行属性赋值

进行重写设置。

var attrs = new XmlAttributes();
var attr = new XmlElementAttribute("actionActuatorFuncParam", typeof(OrientedShoot)) { Namespace = WpmlNamespace.Wpml };
attrs.XmlElements.Add(attr);
// Adds the element to the collection of elements.  
// Creates the XmlAttributeOverrides instance.  
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
// 指定需要替换类型的实际属性名称,不建议手动字符串拼写
attrOverrides.Add(typeof(WpmlAction), nameof(WpmlAction.ActionActuatorFuncParam), attrs);
//构建序列化实例(传入序列化化实例类型)
var serializer = new XmlSerializer(typeof(KmlRoot), overrides,null, new XmlRootAttribute("kml") { Namespace = WpmlNamespace.Kml },null);
var settings = new XmlWriterSettings
{Indent = true,IndentChars = "  ",Encoding = Encoding.UTF8,OmitXmlDeclaration = false, // 保持 XML 声明
};using (var stringWriter = new StringWriter())
using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
{// 序列化对象serializer.Serialize(xmlWriter, kmlRoot);// 获取序列化后的字符串var xmlString = stringWriter.ToString();return xmlString;
}

序列化结果如下:

<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.6"><Document><Folder><Placemark><wpml:actionGroup><wpml:action><!--子类型序列化重写--><wpml:actionActuatorFuncParam><wpml:focusX>0</wpml:focusX></wpml:actionActuatorFuncParam><!--子类型序列化重写--></wpml:action></wpml:actionGroup></Placemark></Document></kml>
http://www.dtcms.com/a/553149.html

相关文章:

  • 【JUnit实战3_19】第十章:用 Maven 3 运行 JUnit 测试(下)
  • wordpress 禁止过滤张家口seo
  • 网站建设的流程该怎么确定自己怎么设计logo制作
  • 3.游戏逆向-pxxx-对照UE源码和IDA分析GName偏移(ida中calloff开头地址的说明)
  • AR智能巡检:开启工业运维的“透视眼”
  • PhotoQt,一款轻量级图片浏览器
  • 什么是一级boot和二级boot
  • 网站开发师招聘网站建设几个要素
  • Java语言处理Js文件内容格式化
  • 力扣Hot100--哈希表--day01
  • 鸿蒙技术知多点,技术深入、鸿蒙开发实战分享(一)——下载功能按钮与全局悬浮窗联动实战开发
  • 安科瑞暖通空调解决方案可覆盖分体空调、中央空调和多联机等类型空调系统,有效帮助用户实现空调系统节能降本
  • 用php做购物网站视频网站建设 翰臣科技公司
  • 本地音乐库嫌麻烦?PlaylistDL+cpolar打造“随身听”云端曲库!
  • 巩义网站建设定制电子商务系统网站开发总结
  • Excel怎么在下拉菜单中选择计算方式?
  • PHY6252国产蓝牙低成本透传芯片BLE5.2智能灯控智能家居
  • unity之线框模式
  • h5游戏免费下载:小飞鱼?
  • 【设计模式】享元模式(Flyweight)大白话讲解!
  • seo网站优化知识网站设计师的工作环境
  • 浅谈onlyoffice开发全流程(一、基础介绍)
  • 金仓KRDS云数据库服务管控平台:构建高效智能的数据库运维体系
  • GMI Cloud:如何构建全球化高性能分布式推理服务?
  • Linux入门攻坚——52、drbd - Distribute Replicated Block Device,分布式复制块设备-1
  • Threat Report ATTCK Mapper(TRAM)安装与配置手册
  • java后端初始化模版
  • WebGPU深度学习前端:基于浏览器的分布式模型推理
  • 深入浅出:增强现实(AR)技术全解析
  • 【进程间通信】--- 匿名管道,命名管道