为什么反序列化子类时会引发 XmlSerializer.UnknownAttribute/UnknownNode 事件?

问题描述 投票:0回答:1

当使用子类时,我在反序列化由 XmlSerializer 生成的 XML 代码时遇到问题。 UnknownAttribute 和 UnknownNode 事件触发,我假设反序列化 XML 时出现错误。事实证明,不设置处理程序或忽略事件仍然可以让反序列化成功。

示例代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace XmlTest
{
    public class Program
    {
        public abstract class ParentClass
        {
            public int Prop1 { get; set; } = 1;
            public int Prop2 { get; set; } = 2;
        }

        public class ChildClassA : ParentClass
        {
            public int PropA3 { get; set; } = 3;
            public int PropA4 { get; set; } = 4;
        }

        public class ChildClassB : ParentClass
        {
            public int PropB5 { get; set; } = 5;
            public int PropB6 { get; set; } = 6;
        }

        [XmlInclude(typeof(ChildClassA))]
        [XmlInclude(typeof(ChildClassB))]
        public class CollectionClass
        {
            public List<ParentClass> classList { get; set; }
        }

        static void Main(string[] args)
        {
            CollectionClass collectionClassWrite = new CollectionClass();
            collectionClassWrite.classList = new List<ParentClass>();
            collectionClassWrite.classList.Add(new ChildClassA());
            collectionClassWrite.classList.Add(new ChildClassB());

            // Serialize the class to a file
            string filePath = Path.GetTempFileName() + ".xml";
            XmlSerializer serializer = new XmlSerializer(typeof(CollectionClass));
            TextWriter writer = new StreamWriter(filePath);
            serializer.Serialize(writer, collectionClassWrite);
            writer.Close();

            XmlSerializer deserializer = new XmlSerializer(typeof(CollectionClass));

            // Event handlers for unknown nodes and attributes -
            serializer.UnknownNode += new
            XmlNodeEventHandler(serializer_UnknownNode);
            serializer.UnknownAttribute += new
            XmlAttributeEventHandler(serializer_UnknownAttribute);

            // Deserialize the class from the file
            FileStream fs = new FileStream(filePath, FileMode.Open);
            CollectionClass classCollectionOpen = (CollectionClass)serializer.Deserialize(fs);
            fs.Close();

            Console.ReadLine();
        }

        private static void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
        {
            Console.WriteLine($"Unknown Attribute at {e.LineNumber}:{e.LinePosition}");
        }

        private static void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
        {
            Console.WriteLine($"Unknown Node at {e.LineNumber}:{e.LinePosition}");
        }
    }
}

生成的 XML 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<CollectionClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <classList>
    <ParentClass xsi:type="ChildClassA">
      <Prop1>1</Prop1>
      <Prop2>2</Prop2>
      <PropA3>3</PropA3>
      <PropA4>4</PropA4>
    </ParentClass>
    <ParentClass xsi:type="ChildClassB">
      <Prop1>1</Prop1>
      <Prop2>2</Prop2>
      <PropB5>5</PropB5>
      <PropB6>6</PropB6>
    </ParentClass>
  </classList>
</CollectionClass>

UnknownAttribute 和 UnknownNode 事件在(行:列)4:28 和 10:28 触发,xsi:type="ChildClassA" 和 xsi:type="ChildClassB" 属性。

看来必须忽略这些事件才能使代码正常工作。 我的问题就变成了: 为什么当 XmlSerializer 清楚地知道如何处理 XML 代码时会引发事件?

c# .net xml-serialization xmlserializer .net-4.8
1个回答
0
投票

因此 XmlSerializer 不知道什么将被序列化为 ParentClass。

解决方案是让它了解可能的类型。
问题是 Array 需要知道除了整个类之外将出现什么类型。

public record CollectionClass
{
    [XmlArrayItem("ChildClassA", typeof(ChildClassA))]
    [XmlArrayItem("ChildClassB", typeof(ChildClassB))]
    public List<ParentClass> ClassList { get; set; } = new();
}
© www.soinside.com 2019 - 2024. All rights reserved.