反序列化可变命名元素并获取这些元素的名称

时间:2016-05-11 11:03:35

标签: c# xml

我有供应商提供的XML,因此我无法修改此XML文件的生成方式。我想将此文件反序列化为对象,但有时会发生我想要获取的重要信息是元素本身的名称。例如:

   <type>
          <BOOL />
   </type>

当类型不是原始类型时,我没有遇到这个问题,因为我会得到这样的结果:

   <type>
          <derived name="CustomDatatype" />
   </type>

该元素将始终命名为&#34;衍生&#34;并有一个属性&#34; name&#34;所以我只检查派生元素是否存在并获取name的值。

回到问题,在&#34;类型&#34; element我有另一个名为&#34; BOOL&#34;但它可能是19个原始数据类型的固定列表中的任何值类型,所以我最终这样做:

public class XmlType
{
  //Here I show just two datatypes but remember that the list is larger
  [XmlElement("BOOL",IsNullable = true)]
  public string boolType{ get; set;}
  [XmlElement("BYTE",IsNullable = true)]
  public string byteType{ get; set;}
  .
  .
  .
  [XmlElement("derived",IsNullable = true)]
  public DerivedTypeXml derivedType{ get; set;}

  [XmlIgnore]
  public string Type
  {
    get
    {
      if (this.boolType != null) 
      {
        return "BOOL";
      } else if (this.byteType != null) {
        return "BYTE";
      }else if(this.derivedType!=null)
      {
        return this.derivedType.Name;
      }else
      {
        return "unknown";
      }
    }
  }

  }
}

正如你所看到的,我必须声明允许它们为null的可能元素,然后逐个检查它们是否存在并告诉它们必须返回什么。这感觉太多的工作和hacky所以我想知道是否有一个通用的解决方案。

编辑:好的,亚历山大的答案是对的,但为了满足我的需要,我不得不稍微调整一下。

        [XmlIgnore]
        public string primitiveType=string.Empty;

        public string Type
        {
            get
            {
                if(primitiveType!=string.Empty)
                {
                    return this.primitiveType;
                }
                else if(this.derivedType!=null)
                {
                    return this.derivedType.Name;

                }else{
                    return "#UNKNOWN";
                }

            }
        }


    private void XmlSerializer_UnknownElement(object sender, XmlElementEventArgs e)
    {
        var obj = (TypeXml)e.ObjectBeingDeserialized;
        obj.primitiveType = e.Element.Name;
    }

1 个答案:

答案 0 :(得分:0)

尝试这样的事情:

public class XmlType
{
    [XmlElement("derived", IsNullable = true)]
    public DerivedTypeXml derivedType { get; set; }

    // No need [XmlIgnore]
    public string Type { get; set; }
}

UnknownElement的实例上创建XmlSerializer事件处理程序。

xmlSerializer.UnknownElement += XmlSerializer_UnknownElement;

private void XmlSerializer_UnknownElement(object sender, XmlElementEventArgs e)
{
    var obj = (XmlType)e.ObjectBeingDeserialized;
    obj.Type = e.Element.Name;
}

这就是全部!

当序列化器遇到未知标签时,如BOOL,BYTE等将被称为事件处理程序。因此为Type属性分配了此标记的名称。

请务必删除XmlIgnore属性,以便为此属性调用事件处理程序。