【问题标题】:c# XmlSerializer deserializer missing default namespacec# XmlSerializer 反序列化器缺少默认命名空间
【发布时间】:2021-11-03 01:56:03
【问题描述】:

以下是我目前正在处理的集成中的示例负载响应。响应没有设置默认命名空间(示例中的 xml2 变量),问题是 XmlSerializer 不假定默认命名空间是“d”。我尝试在 XMLSerializer 构造函数中设置默认命名空间,但这也不起作用。同样,我不能指望“服务”更新/修复他们的一面。我可以传递一些其他设置来正确填充类吗?

谢谢, 查克

using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace TestXmlNamespace
{
    [XmlRoot(ElementName = "root", Namespace = "my_test_ns1")]
    public class Test
    {
        public string name { get; set; }
        public int age { get; set; }

        [XmlElement(Namespace = "my_test_ns2")]
        public int ageInMonths { get; set; }

        public override bool Equals(object obj)
        {
            return obj is Test b && name == b.name && age == b.age && ageInMonths == b.ageInMonths;
        }

        public void Run(string str, string name)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Test));
            using (StringReader rStream = new StringReader(str))
            {
                Test test = serializer.Deserialize(rStream) as Test;
                Console.Out.WriteLine(test.Equals(this) ? $"{name} equals expected" : $"{name} does not equal expected");
            }
        }
    }

    class Program
    {
        const string xml1 = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
<d:root xmlns:d=""my_test_ns1"" xmlns:v=""my_test_ns2"">
  <d:name>Bill</d:name>
  <d:age>32</d:age>
  <v:ageInMonths>384</v:ageInMonths>
</d:root>
";

        const string xml2 = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
<d:root xmlns:d=""my_test_ns1"" xmlns:v=""my_test_ns2"">
  <name>Bill</name>
  <age>32</age>
  <v:ageInMonths>384</v:ageInMonths>
</d:root>
";

        static void Main(string[] args)
        {
            Test expected = new Test()
            {
                name = "Bill",
                age = 32,
                ageInMonths = 384
            };

            expected.Run(xml1, "xml1");
            expected.Run(xml2, "xml2");
        }
    }
}

【问题讨论】:

    标签: c# xmlserializer


    【解决方案1】:

    我找到了解决方案,并将其发布给将来可能遇到此问题的人,希望我能帮助他们节省一些时间。

    简单地说,当一个元素没有命名空间前缀时,XmlSerializer 认为它不是命名空间的一部分,因此在元素属性中指定一个空的命名空间来处理这个问题。请参阅下面的更新示例代码。

    using System;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    namespace TestXmlNamespace
    {
        public class CustomXmlTextReader : XmlTextReader
        {
            private readonly string DefaultNamespace = String.Empty;
    
            public CustomXmlTextReader(StringReader reader, string defaultNamespace) : base(reader)
            {
                DefaultNamespace = defaultNamespace;
            }
    
            public override string NamespaceURI => String.IsNullOrEmpty(base.NamespaceURI) ? DefaultNamespace : base.NamespaceURI;
        };
    
        [XmlRoot(ElementName = "root", Namespace = "my_test_ns1")]
        public class Test
        {
            [XmlElement("name", Namespace = "")] // Set namespace to empty string when no namespace prefix specified in xml
            public string name { get; set; }
    
            [XmlElement("age", Namespace = "")] // Set namespace to empty string when no namespace prefix specified in xml
            public int age { get; set; }
    
            [XmlElement(Namespace = "my_test_ns2")]
            public int ageInMonths { get; set; }
    
            public override bool Equals(object obj)
            {
                return obj is Test b && name == b.name && age == b.age && ageInMonths == b.ageInMonths;
            }
    
            public void Run(string str, string name)
            {
                using (StringReader rStream = new StringReader(str))
                {
                    //using (XmlTextReader tr = new CustomXmlTextReader(rStream, "my_test_ns1"))
                    using (XmlTextReader tr = new XmlTextReader(rStream))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(Test));
                        Test test = serializer.Deserialize(tr) as Test;
                        Console.Out.WriteLine(test.Equals(this) ? $"{name} equals expected" : $"{name} does not equal expected");
                    }
                }
            }
        }
    
        class Program
        {
            const string xml = @"<?xml version=""1.0"" encoding=""UTF-8"" ?>
    <d:root xmlns:d=""my_test_ns1"" xmlns:v=""my_test_ns2"">
      <name>Bill</name>
      <age>32</age>
      <v:ageInMonths>384</v:ageInMonths>
    </d:root>
    ";
    
            static void Main(string[] args)
            {
                Test expected = new Test()
                {
                    name = "Bill",
                    age = 32,
                    ageInMonths = 384
                };
    
                expected.Run(xml, "xml1");
            }
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 2018-02-19
      • 2021-09-13
      • 1970-01-01
      • 2016-09-24
      • 2018-10-29
      • 1970-01-01
      相关资源
      最近更新 更多