C# - 反序列化XML - XmlText获取Null而不是字符串本身

时间:2016-12-20 05:00:54

标签: c# xml parsing serialization

我正在尝试从字符串中解析XML消息。 我得到的字符串是这个 -

<Instance_Updated>
  <Instance>
    <Field Name="INSTANCE_LABEL">00010541</Field>
    <Field Name="MAT_ID">TEST</Field>
    <Field Name="DEVICE_ID">TEST</Field>
  </Instance>
  <Item>
    <Field Name="MATERIAL_ID">TEST</Field>
    <Field Name="TITLE">TEST</Field>
    <Field Name="ON_AIR_DURATION">A</Field>
  </Item>
</Instance_Updated>

InstanceUpdated类本身是:

    [XmlType("Instance_Updated"), Serializable]
    public class InstanceUpdated : SnellMessage
    {
        public InstanceUpdated()
        {
            InstanceFields = new List<Field>()
            {
                new Field() { Name = "INSTANCE_LABEL" },
                new Field() { Name = "MAT_ID" },
                new Field() { Name = "DEVICE_ID" }
            };

            ItemFields = new List<Field>()
            {
                new Field() { Name = "MATERIAL_ID" },
                new Field() { Name = "TITLE" },
                new Field() { Name = "ON_AIR_DURATION" }
            };
        }

        [XmlArray("Instance")]
        [XmlArrayItem("Field")]
        public List<Field> InstanceFields { get; set; }

        [XmlArray("Item")]
        [XmlArrayItem("Field")]
        public List<Field> ItemFields { get; set; }
   }

    [XmlType("Field"), Serializable]
    public class Field
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }

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

当我尝试解析消息时 -

InstanceUpdated instanceUpdatedMessage = SnellMessage.Deserialize<InstanceUpdated>(i_RootMessage.ToString()); 

在'Field'对象中,我得到NULL值而不是字符串本身。

例如: 我假设字段'INSTANCE_LABEL'的Value属性应为'00010541',但在内部我得到一个NULL值。

为什么?

1 个答案:

答案 0 :(得分:1)

问题不在于Field.Value的值是否为空。问题是您要在InstanceFields构造函数中分配ItemFieldsInstanceUpdated列表,之后XmlSerializer 追加 XML文件中的反序列化字段。如果重新序列化XML,您将看到每个字段都已重复:

  <Instance>
    <Field Name="INSTANCE_LABEL" />
    <Field Name="MAT_ID" />
    <Field Name="DEVICE_ID" />
    <Field Name="INSTANCE_LABEL">00010541</Field>
    <Field Name="MAT_ID">TEST</Field>
    <Field Name="DEVICE_ID">TEST</Field>
  </Instance>

示例repo fiddle

有关解决原因的说明,请参阅XML Deserialization of collection property with code defaults

您的解决方法包括:

  • 将集合初始化移出构造函数并进入某个工厂。

  • 序列化代理数组属性。由于数组是只读的,因此必须在完全填充后重新设置数组,例如:

    [XmlIgnore]
    public List<Field> InstanceFields { get; set; }
    
    [XmlArray("Instance")]
    [XmlArrayItem("Field")]
    public Field [] InstanceFieldsArray
    {
        get
        {
            if (InstanceFields == null)
                return null;
            return InstanceFields.ToArray();
        }
        set
        {
            (InstanceFields = InstanceFields ?? new List<Field>()).Clear();
            InstanceFields.AddRange(value ?? Enumerable.Empty<Field>());
        }
    }
    

    示例fixed fiddle