【问题标题】:C# - Deserializing XML - XmlText gets Null instead of string itselfC# - 反序列化 XML - XmlText 获取 Null 而不是字符串本身
【发布时间】:2016-12-20 05:00:53
【问题描述】:

我正在尝试从字符串中解析 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()); 

在“字段”对象中,我得到的是 NULL 值而不是字符串本身。

例如: 我假设字段 'INSTANCE_LABEL' 的 Value 属性应该是 '00010541' 但在里面我得到一个 NULL 值。

为什么会这样?

【问题讨论】:

    标签: c# xml parsing serialization


    【解决方案1】:

    问题不在于Field.Value 的值返回为空。问题是您正在为InstanceUpdated 分配构造函数 中的InstanceFields 和ItemFields 列表,然后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。

    【讨论】:

    • 谢谢,我删除了InstanceUpdated的构造函数,XmlSerializer确实自己添加了所有字段。
    猜你喜欢
    • 2011-01-21
    • 2011-08-04
    • 1970-01-01
    • 2013-01-16
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多