为了账号安全,请及时绑定邮箱和手机立即绑定

XML 未反序列化为正确的类,并且之后未使用 xsi:type 属性进行序列化

XML 未反序列化为正确的类,并且之后未使用 xsi:type 属性进行序列化

C#
吃鸡游戏 2023-07-22 16:02:13
在下面的代码片段中,我尝试反序列化在Animal记录上具有类型属性的 XML,将它们标识为Cat或Dog,两者都继承自Animal。反序列化时,这些记录全部显示为Animal.然后,当尝试序列化该对象时(反序列化之后), 和xsi:type="Dog"不会xsi:type="Cat"出现在 XML 中。我不确定这是否是由于我如何装饰类或在我的序列化器/反序列化器实现中造成的。如果可能的话,首选类中的解决方案而不是序列化器/反序列化器包装方法。代码:using System;  using System.IO; using System.Text;using System.Xml;using System.Xml.Serialization; namespace sandbox{    public partial class Program    {        static void Main(string[] args)        {             string xml =                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +                "<OuterClass xmlns=\"http://myschema.com/\">" +                "   <Animals>" +                "      <Animal xmlns:xsi=\"http://myschema.com/\" xsi:type=\"Dog\">" +                "         <Name>Watson</Name>" +                "         <Height>10</Height>" +                "         <Weight>10</Weight>" +                "         <Paws>4</Paws>" +                "         <Woof>True</Woof>" +                "      </Animal>" +                "      <Animal xmlns:xsi=\"http://myschema.com/\" xsi:type=\"Cat\">" +                "         <Name>Hermy</Name>" +                "         <Height>10</Height>" +                "         <Weight>10</Weight>" +                "         <Paws>4</Paws>" +                "         <Meow>True</Meow>" +                "      </Animal>" +                "   </Animals>" +                "</OuterClass>";            OuterClass data = null;            try            {                data = DeserializeXml<OuterClass>(xml);                foreach (Animal curr in data.Animals) Console.WriteLine(curr.Name + ": " + curr.GetType().ToString());            }            catch (Exception e)            {                Console.WriteLine(e.ToString());                Console.WriteLine(e.Message);            }            Console.WriteLine(SerializeXml(data));            Console.ReadLine();         }
查看完整描述

2 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

您的示例中有几个问题:

  • 该模型与 xml 不匹配

  • 每个 Animal 元素都会覆盖 xsi 命名空间

  • 序列化不支持布尔值

请在下面找到有关问题的更多详细信息:

1.模型与xml不匹配

当您指定XmlArrayItem XmlSerializer时,将使用类型名称作为元素名称,或者您可以通过显式提供ElementName来更改它。如果您使用注释数组属性,XmlArrayItem您将得到以下输出:

Console.WriteLine(SerializeXml(new OuterClass { Animals = new Animal[] { new Cat(), new Dog() } }));


<OuterClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://myschema.com/">

  <Animals>

    <Cat>

      <Height>0</Height>

      <Weight>0</Weight>

      <Paws>0</Paws>

      <Meow>false</Meow>

    </Cat>

    <Dog>

      <Height>0</Height>

      <Weight>0</Weight>

      <Paws>0</Paws>

      <Woof>false</Woof>

    </Dog>

  </Animals>

</OuterClass>

如果不注释,您将获得 xsi:type 属性定义的类型的输出:


<OuterClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://myschema.com/">

  <Animals>

    <Animal xsi:type="Cat">

      <Height>0</Height>

      <Weight>0</Weight>

      <Paws>0</Paws>

      <Meow>false</Meow>

    </Animal>

    <Animal xsi:type="Dog">

      <Height>0</Height>

      <Weight>0</Weight>

      <Paws>0</Paws>

      <Woof>false</Woof>

    </Animal>

  </Animals>

</OuterClass>

XmlInclude在这种情况下,您必须向基类添加属性。

2. 每个 Animal 元素都会覆盖 xsi 命名空间

http://www.w3.org/2001/XMLSchema-instance是W3C中定义的特殊命名空间,可帮助序列化程序了解 XML 元素中的类型。在您的输入 xml 中,每个 Animal 元素都会使用自定义的http://myschema.com/覆盖此名称空间,因此当序列化程序遇到它时xsi:type="Cat",它不知道它的含义。维基百科是了解 XML 命名空间的一个很好的起点:https://en.wikipedia.org/wiki/XML_namespace

3. XML 中的布尔值

W3C 将布尔数据类型定义为“true”、“false”、“0”和“1”,因此如果您使用值“ True ”反序列化布尔值,则会出现异常。您可能会在网上找到解决方法,但我认为您的输入 XML 格式错误,您需要将 XML 中的布尔值小写。


查看完整回答
反对 回复 2023-07-22
?
慕丝7291255

TA贡献1859条经验 获得超6个赞

您需要正确创建类:


            OuterClass outerClass = new OuterClass()

            {

                Animals = new Animal[] {

                    new Dog() { Name = "Watson", Height = 10, Weight = 10, Paws = 4},

                    new Cat() { Name = "Hermy", Height = 10, Weight = 10, Paws = 4}

                }

            };


查看完整回答
反对 回复 2023-07-22
  • 2 回答
  • 0 关注
  • 153 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信