C# XmlSerializer序列化时XmlElement带冒号特殊字符被转义如何解决?
问题根源
XML规范中冒号:是命名空间前缀与本地节点名的分隔符,不属于普通节点名称可用字符。你直接将带冒号的字符串传入[XmlElement]的节点名参数时,XmlSerializer无法识别为合法的命名空间前缀+本地名组合,就会自动将冒号转义为Unicode编码格式_x003A_,你之前尝试的C#字符串转义符号(反斜杠、@、$)仅处理C#代码层面的字符串转义,和XML序列化的转义逻辑无关,因此无效。
解决方案
通过显式声明命名空间前缀与命名空间的映射关系实现带前缀的节点输出,不需要手动替换字符串,操作步骤如下:
步骤1:修改特性配置,拆分命名空间与本地节点名
不要将前缀写在XmlElement的第一个参数(节点名)里,而是通过Namespace参数指定该节点对应的命名空间,本地名只写冒号后面的部分:
// 原错误写法 // [XmlElement("Test:Pool1")] // 修改后写法,Pool1是本地节点名,Namespace填该前缀对应的命名空间地址 [XmlElement("Pool1", Namespace = "http://www.foo1.com/bar/test/")] public Tester Admin { get => this.adminField; set => this.adminField = value; }
如果你需要根节点用自定义前缀,同步修改XmlRoot配置即可,节点名只写冒号后的部分。
步骤2:序列化时注册命名空间前缀和对应地址的映射
在XmlSerializerNamespaces中添加你需要的前缀(比如你示例里的Test或者期望输出的q1)与对应命名空间的映射关系:
private void Serlise(Interface request) { var xsSubmit = new XmlSerializer(typeof(Interface)); var ns = new XmlSerializerNamespaces(); // 注册前缀和对应命名空间的映射,第一个参数是你要的前缀,第二个是命名空间地址 ns.Add("Test", "http://www.foo1.com/bar/test/"); // 如果你需要期望示例里的q1前缀,就改成 ns.Add("q1", "http://www.foo1.com/bar/test/"); var xml = ""; using (var encoder = new CustomEncoder()) { using (var writer = XmlWriter.Create(encoder)) { xsSubmit.Serialize(writer, request, ns); xml = encoder.ToString(); } } File.WriteAllText(@"output.xml", xml); }
效果说明
序列化时XmlSerializer会自动匹配节点的Namespace属性和你注册的前缀映射,输出<Test:Pool1>或者<q1:Pool1>格式的节点,不会再出现转义后的编码字符串。
内容的提问来源于stack exchange,提问作者jidh
相关产品推荐
相关产品推荐

