将c#中的嵌套列表序列化为XML

将c#中的嵌套列表序列化为XML,c#,xml,nested-lists,C#,Xml,Nested Lists,我在c#中有一个嵌套列表:list,需要将其序列化为xml 我的代码: [XmlRoot("AlertInfo")] public class AlertInfo { [XmlElement("TargetID")] public string strTargetId { get; set; } [XmlElement("ChannelID")] public string strChId { get; set; } [XmlElement("Time

我在c#中有一个嵌套列表:
list
,需要将其序列化为xml

我的代码:

[XmlRoot("AlertInfo")]
public class AlertInfo
{
    [XmlElement("TargetID")]
    public string strTargetId { get; set; }

    [XmlElement("ChannelID")]
    public string strChId { get; set; }

    [XmlElement("Timestamp")]
    public string strTimestamp { get; set; }

    [XmlElement("Object")]
    public RectObject rfObject { get; set; }

    [XmlArray("Polygons")]
    [XmlArrayItem("Polygon")]
    public List<List<OVReady.Types.PointF[]>> lstPolygons { get; set; }
}

public class RectObject
{
    [XmlAttribute("x")]
    public float x { get; set; }
    [XmlAttribute("y")]
    public float y { get; set; }
    [XmlAttribute("width")]
    public float width { get; set; }
    [XmlAttribute("height")]
    public float height { get; set; }
}
[XmlRoot(“警报信息”)]
公共类警报信息
{
[XmlElement(“TargetID”)]
公共字符串strTargetId{get;set;}
[XmlElement(“ChannelID”)]
公共字符串strChId{get;set;}
[XmlElement(“时间戳”)]
公共字符串strTimestamp{get;set;}
[XmlElement(“对象”)]
公共RectObject rfObject{get;set;}
[XmlArray(“多边形”)]
[XmlArrayItem(“多边形”)]
公共列表{get;set;}
}
公共类对象
{
[XmlAttribute(“x”)]
公共浮点x{get;set;}
[xmldattribute(“y”)]
公共浮点y{get;set;}
[XmlAttribute(“宽度”)]
公共浮点宽度{get;set;}
[XmlAttribute(“高度”)]
公共浮动高度{get;set;}
}
我得到的是:

<AlertInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TargetID>730</TargetID>
  <ChannelID>613</ChannelID>
  <Timestamp>2014-09-26 19:56:07:5660</Timestamp>
  <Object x="0.24375" y="0.025" width="0.259375" height="0.9375001" />
  <Polygons>
    <Polygon>
      <ArrayOfPointF>
        <PointF>
          <X xmlns="http://www.objectvideo.com/schemas/ovready">0.30625</X>
          <Y xmlns="http://www.objectvideo.com/schemas/ovready">0.9375</Y>
        </PointF>
        <PointF>
          <X xmlns="http://www.objectvideo.com/schemas/ovready">0.696875</X>
          <Y xmlns="http://www.objectvideo.com/schemas/ovready">0.9416667</Y>
        </PointF>
      </ArrayOfPointF>
    </Polygon>
  </Polygons>
</AlertInfo>

730
613
2014-09-26 19:56:07:5660
0.30625
0.9375
0.696875
0.9416667
我想要的是:

<AlertInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TargetID>730</TargetID>
  <ChannelID>613</ChannelID>
  <Timestamp>2014-09-26 19:56:07:5660</Timestamp>
  <Object x="0.24375" y="0.025" width="0.259375" height="0.9375001" />
  <Polygons>
    <Polygon>
        <Point x=0.30625 y=0.9375>
        <Point x=0.696875 y=0.9416667>
      </Polygon>
  </Polygons>
</AlertInfo>

730
613
2014-09-26 19:56:07:5660
如何移除标记并根据需要设置位置x和y

  • 如果嵌套太多,请删除嵌套最多的数组:

    public List<List<OVReady.Types.PointF[]>> lstPolygons { get; set; }
    
    公共列表{get;set;}
    

    公共列表{get;set;}
    
    • 如果可以修改OVReady.Types.PointF类,则可以修饰它,使其属性正确地序列化为属性,而不是新元素
    • 如果没有,请遵循以下步骤

  • 让我们从最简单的方法开始。重新设计属性以简化序列化

    为了实现这一点,我必须引入一个新类多边形:

    public class Polygon
    {
        [XmlElement("Point")]
        public List<PointF> Points { get; set; }
    }
    
    公共类多边形
    {
    [XmlElement(“点”)]
    公共列表点{get;set;}
    }
    
    然后,您必须重新设计您的财产:

    [XmlArray("Polygons")]
    [XmlArrayItem("Polygon")]
    public List<Polygon> lstPolygons { get; set; }
    
    [XmlArray(“多边形”)]
    [XmlArrayItem(“多边形”)]
    公共列表{get;set;}
    
    如果你没有必要像本例中那样重新设计该房产,下面你可以找到一个同样可行的方法。这不是清洁,但它的工作,它是简单的

    其思想是XmlIgnore您的当前属性,以防止XML序列化程序处理它,然后使用一个仅为序列化设计的附加getter,该getter将使用LINQ动态地重新格式化数据,以便为序列化程序做好准备。查看代码:

    [XmlRoot("AlertInfo")]
    public class AlertInfo
    {
        [XmlElement("TargetID")]
        public string strTargetId { get; set; }
    
        [XmlElement("ChannelID")]
        public string strChId { get; set; }
    
        [XmlElement("Timestamp")]
        public string strTimestamp { get; set; }
    
        [XmlElement("Object")]
        public RectObject rfObject { get; set; }
    
        [XmlIgnore]
        public List<List<PointF[]>> lstPolygons { get; set; }
    
        [XmlArray("Polygons")]
        [XmlArrayItem("Polygon")]
        public List<Polygon> Polygons
        {
            get {
                return lstPolygons.Select(p => new Polygon() { Points = p.SelectMany(lp => lp).ToList() }).ToList();
            }
        }
    }
    
    [XmlRoot(“警报信息”)]
    公共类警报信息
    {
    [XmlElement(“TargetID”)]
    公共字符串strTargetId{get;set;}
    [XmlElement(“ChannelID”)]
    公共字符串strChId{get;set;}
    [XmlElement(“时间戳”)]
    公共字符串strTimestamp{get;set;}
    [XmlElement(“对象”)]
    公共RectObject rfObject{get;set;}
    [XmlIgnore]
    公共列表{get;set;}
    [XmlArray(“多边形”)]
    [XmlArrayItem(“多边形”)]
    公共列表多边形
    {
    得到{
    返回lstPolygons.Select(p=>newpolygon(){Points=p.SelectMany(lp=>lp.ToList()}).ToList();
    }
    }
    }
    
    序列化上述AlertInfo多边形属性的结果如下:

    <Polygons>
      <Polygon>
        <Point x="0" y="0" />
        <Point x="0" y="0" />
      </Polygon>
    </Polygons>
    
    
    
    另一种方法是实现IXmlSerializable并自己控制序列化。查看这篇关于如何操作的文章:


    您需要在
    AlertInfo
    类中实现
    序列化
    反序列化
    方法来实现这一点。您可以实现
    IXmlSerializable
    并在
    ReadXml
    WriteXml
    方法中处理序列化和反序列化。juharr的优点。我不认为你只能通过属性来处理。要正确实现IXmlSerializable,请检查:另一个选项是创建您自己的多边形和点类。对我来说非常有效!非常感谢。
    <Polygons>
      <Polygon>
        <Point x="0" y="0" />
        <Point x="0" y="0" />
      </Polygon>
    </Polygons>