我正在尝试从字符串中解析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值。
为什么?
答案 0 :(得分:1)
问题不在于Field.Value
的值是否为空。问题是您要在InstanceFields
的构造函数中分配ItemFields
和InstanceUpdated
列表,之后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。