You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何反序列化包含未知xsi:type属性的XML?

处理XML反序列化中未知xsi:type的问题

问题场景

反序列化XML时,<AutxObject>节点的xsi:type可能新增未知类型,但所有节点都包含固定且始终存在的子节点(如ID、Name、ProcessID等),需要忽略类型差异,直接读取这些固定字段。

XML示例

<AutxObject xsi:type="TYPEA">
  <ID>6cbe7c6f-79e8-4006-b7e9-11e25e2a0f8e</ID>
  <Name>Queue</Name>
  <ProcessID>eaab59cd-2be4-46fe-86c4-ee96c340c061</ProcessID>
  <IsRemoteExecutionEnabled>false</IsRemoteExecutionEnabled>
  <IsolationPlatform>x86</IsolationPlatform>
  <IsolationSessionType>Current</IsolationSessionType>
  <Items />
  <RootPath>Global Objects</RootPath>
</AutxObject>
<AutxObject xsi:type="TYPEB">
  <ID>9c643856-5f0c-497a-b212-a2e456d1a821</ID>
  <Name>Sample</Name>
  <ProcessID>eaab59cd-2be4-46fe-86c4-ee96c340c061</ProcessID>
  <IsRemoteExecutionEnabled>false</IsRemoteExecutionEnabled>
  <IsolationPlatform>x86</IsolationPlatform>
  <IsolationSessionType>Current</IsolationSessionType>
  <Items />
  <RootPath>Global Objects</RootPath>
  <Type>
    <ID>75f2bd69-8bfc-41ba-a3fc-32e1a438b23a</ID>
    <Name>Object</Name>
    <FullName>System.Object</FullName>
    <Assembly>mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</Assembly>
  </Type>
</AutxObject>

现有类定义

[XmlInclude(typeof(TYPEA))]
[XmlInclude(typeof(TYPEB))]
public class GlobalVariable
{
    [XmlElement("ID")]
    public Guid Id { get; set; }

    [XmlElement("Name")]
    public string Name { get; set; } = string.Empty;

    [XmlElement("RootPath")]
    public string RootPath { get; set; } = string.Empty;
}

[XmlType(TypeName = "TYPEA")]
public class TYPEA: GlobalVariable { }

[XmlType(TypeName = "TYPEB")]
public class TYPEB: GlobalVariable { }

解决方案

1. 完善基类,包含所有固定子节点

首先将所有固定存在的子节点添加到GlobalVariable基类中,确保所有需要读取的字段都被映射:

public class GlobalVariable
{
    [XmlElement("ID")]
    public Guid Id { get; set; }

    [XmlElement("Name")]
    public string Name { get; set; } = string.Empty;

    [XmlElement("RootPath")]
    public string RootPath { get; set; } = string.Empty;

    [XmlElement("ProcessID")]
    public Guid ProcessId { get; set; }

    [XmlElement("IsRemoteExecutionEnabled")]
    public bool IsRemoteExecutionEnabled { get; set; }

    [XmlElement("IsolationPlatform")]
    public string IsolationPlatform { get; set; } = string.Empty;

    [XmlElement("IsolationSessionType")]
    public string IsolationSessionType { get; set; } = string.Empty;

    // 忽略不需要解析的节点,或用XmlNode保留原始内容
    [XmlElement("Items")]
    public XmlNode? Items { get; set; }
}

2. 方法一:手动遍历XmlReader反序列化

直接遍历XML节点,将每个<AutxObject>节点反序列化为GlobalVariable,完全忽略xsi:type:

var autxObjects = new List<GlobalVariable>();
var serializer = new XmlSerializer(typeof(GlobalVariable));

using (var reader = XmlReader.Create("your-xml-file-path.xml"))
{
    while (reader.Read())
    {
        if (reader.NodeType == XmlNodeType.Element && reader.Name == "AutxObject")
        {
            var obj = (GlobalVariable)serializer.Deserialize(reader)!;
            autxObjects.Add(obj);
        }
    }
}

3. 方法二:处理UnknownType事件(适用于父类包含列表的场景)

如果XML有根节点,且用包含AutxObject列表的父类反序列化,可通过UnknownType事件将未知类型映射到基类:

// 定义根节点类
[XmlRoot("Root")]
public class RootObject
{
    [XmlElement("AutxObject")]
    public List<GlobalVariable> AutxObjects { get; set; } = new();
}

// 反序列化时处理未知类型
var serializer = new XmlSerializer(typeof(RootObject));
serializer.UnknownType += (sender, e) =>
{
    // 遇到未知xsi:type时,用GlobalVariable实例接收
    e.ObjectBeingDeserialized = new GlobalVariable();
};

using (var reader = XmlReader.Create("your-xml-file-path.xml"))
{
    var root = (RootObject)serializer.Deserialize(reader)!;
    // 使用root.AutxObjects
}

内容的提问来源于stack exchange,提问作者sumit kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:36:00