加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 22:31:11 所属栏目:百科 来源:网络整理
导读:我有一个 XML文档,使用反序列化,有没有办法将两个元素组合成一个对象? XML示例: Parameter13/Parameter1Parameter24/Parameter2 我想创建一个包含项目3和4的列表(类型为Parameter). 我尝试过使用XmlArrayItem,例如: [XmlArrayItem("Parameter1")][XmlArra
我有一个 XML文档,使用反序列化,有没有办法将两个元素组合成一个对象?

XML示例:

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

我想创建一个包含项目3和4的列表(类型为Parameter).

我尝试过使用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:

>使用[XmlElementAttribute(String,?Type)]对您的Parameter类进行子类化,并为每个元素名称指定不同的类型.实例化的特定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; }
}

>如果要使用相同的参数类型来反序列化< 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数组相同数量的条目,其中的枚举值将指示实际遇到的每个参数的XML元素名称.
>作为选项2的变体,如果您不需要捕获XML元素名称并且只想反序列化值,则可以创建“假”选择数组属性,如下所示:

[XmlType("Root")]
public class RootObject
{
    [XmlElement("Parameter1",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并显示以下消息:

06003

原型fiddle显示每个选项.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读