2014-09-26 1 views
0

У меня есть вложенный список в C#: List<List<OVReady.Types.PointF[]>> и она должна быть сериализации в XMLСериализация списка вложенной в C# для 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; } 
} 

Что я получаю:

<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> 

Что я хочу:

<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> 

H ow я могу удалить тег и установить положение x и y, как я хочу?

+0

Вы должны реализовать '' Serialize' и методы Deserialize' в вашем 'AlertInfo' класса для достижения этой цели –

+0

Вы могли бы реализовать' IXmlSerializable' и обрабатывать сериализации и десериализация в методах 'ReadXml' и' WriteXml'. – juharr

+0

Хорошие очки от juharr. Я не думаю, что вы можете справиться только с атрибутами.Для правильной реализации IXmlSerializable проверьте: http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly –

ответ

0
  1. Вы вложенными много, удалить наиболее вложенную массив:

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

    к

    public List<List<OVReady.Types.PointF>> lstPolygons { get; set; } 
    
    • , если вы можете изменить класс OVReady.Types.PointF, чем украсить его надлежащим образом сериализовать свои свойства для атрибутов вместо новых элементов
    • , если нет, то следовать этому answer
0

Давайте начнем с самого простого подхода возможно. Перепроектируйте свою собственность для упрощения сериализации.

Для того, чтобы достичь этого я должен был ввести новый класс Polygon:

public class Polygon 
{ 
    [XmlElement("Point")] 
    public List<PointF> Points { get; set; } 
} 

И тогда вам придется перестроить свою собственность, чтобы быть:

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

Если вы не есть роскошь, чтобы перепроектировать это свойство, как в этом примере, ниже вы можете найти хак, который может работать. Это не для чистки, но это работает, и это просто.

Идея состоит в том, чтобы XmlИгнорировать ваш текущий атрибут, чтобы предотвратить его обработку XML-сериализатором, а затем использовать один дополнительный геттер, предназначенный только для сериализации, который будет динамически преобразовывать данные с помощью 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(); 
     } 
    } 
} 

Результат сериализации выше AlertInfo Polygons свойства является:

<Polygons> 
    <Polygon> 
    <Point x="0" y="0" /> 
    <Point x="0" y="0" /> 
    </Polygon> 
</Polygons> 

Альтернативный подход заключается в реализации IXmlSerializable и контролировать сериализации себя. Проверьте эту статью о том, как это сделать:

http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly