gpt4 book ai didi

c# - Xml 反序列化 - 将两个元素合并为一个 List 对象

转载 作者:数据小太阳 更新时间:2023-10-29 02:11:57 27 4
gpt4 key购买 nike

我有一个 XML 文档,使用反序列化,有没有办法将两个元素组合成一个对象?

XML 示例:

<Parameter1>3</Parameter1>
<Parameter2>4</Parameter2>

我想创建一个包含项目 3 和 4 的列表(参数类型)。

我试过使用 XmlArrayItem,例如:

[XmlArrayItem("Parameter1")]
[XmlArrayItem("Parameter2")]
[XmlArray]
public Parameter[] Parameters; // have also tried this as public List<Parameter> Parameters = new List<Parameter>();

我试过使用 XmlElements(但我不知道如何组合它们):

[XmlElement("Parameter1")]
public List<Parameter> Parameters = new List<Parameter>();

除了创建两个单独的列表并在稍后将它们合并之外,有什么方法可以做到这一点?

请注意,不能更改 XML 格式。

最佳答案

您的 XML 具有包含 choice 的架构元素。选择元素表示一组固定元素中的一个 -- <Parameter1><Parameter2>在您的情况下——将出现在 XML 中。 XmlSerializer支持选择元素,如 Choice Element Binding Support 中所述:

If individual choice elements' types differ along with their names, Xsd.exe applies only XmlElementAttribute attributes to a public member. If they differ only by name, Xsd.exe applies an XmlChoiceIdentifierAttribute in addition, and adds extra logic for making the choice.

因此,您有以下选项来反序列化您的 XML:

  1. 子类化您的 Parameter类并为每个元素名称指定不同的类型,使用 [XmlElementAttribute(String, Type)] .具体Parameter实例化的子类将因此捕获 XML 元素名称。

    即你可以这样做:

    public abstract class Parameter
    {
    [XmlText]
    public string Value { get; set; } // Could be int if you prefer.
    }

    public class Parameter1 : Parameter
    {
    }

    public class Parameter2 : Parameter
    {
    }

    [XmlType("Root")]
    public class RootObject
    {
    [XmlElement("Parameter1", typeof(Parameter1))]
    [XmlElement("Parameter2", typeof(Parameter2))]
    public Parameter[] Parameters { get; set; }
    }
  2. 如果你想使用相同的Parameter类型反序列化 <Parameter1><Parameter2>元素,必须引入辅助 XmlChoiceIdentifierAttribute 用于捕获 XML 元素名称的数组:

    public class Parameter
    {
    [XmlText]
    public string Value { get; set; }
    }

    [XmlType("Root")]
    public class RootObject
    {
    [XmlElement("Parameter1", typeof(Parameter))]
    [XmlElement("Parameter2", typeof(Parameter))]
    [XmlChoiceIdentifier("ParametersElementName")]
    public Parameter[] Parameters { get; set; }

    [XmlIgnore]
    public ParametersChoiceType[] ParametersElementName { get; set; }
    }

    [XmlType(IncludeInSchema = false)]
    public enum ParametersChoiceType
    {
    Parameter1,
    Parameter2,
    }

    反序列化后,ParametersElementName数组将具有与 Parameters 相同数量的条目数组,以及 enum其中的值将指示每个参数实际遇到的 XML 元素名称。

  3. 作为选项 2 的变体,如果您不需要捕获 XML 元素名称而只想反序列化值,您可以创建一个“假的”选择数组属性,如下所示:

    < p>

    [XmlType("Root")]
    public class RootObject
    {
    [XmlElement("Parameter1", typeof(Parameter))]
    [XmlElement("Parameter2", typeof(Parameter))]
    [XmlChoiceIdentifier("ParametersElementName")]
    public Parameter[] Parameters { get; set; }

    [XmlIgnore]
    public ParametersChoiceType[] ParametersElementName
    {
    get
    {
    if (Parameters == null)
    return null;
    return Parameters.Select(p => ParametersChoiceType.Parameter1).ToArray();// Arbitrarily return ItemsChoiceType.Parameter1
    }
    set
    {
    // Do nothing - don't care.
    }
    }
    }

XmlSerializer要求您使用这两个选项之一。如果无法通过类型或项目选择标识符确定正确的元素名称,它将抛出 InvalidOperationException。带有消息:

You need to add XmlChoiceIdentifierAttribute to the 'Parameters' member.

原型(prototype) fiddle显示每个选项。

关于c# - Xml 反序列化 - 将两个元素合并为一个 List<T> 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37307203/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com