如何为List <Custom>实现设置XmlArrayItem元素名称?

Ody*_*dys 17 .net c# xml xml-serialization

我想创建一个自定义XML结构,如下所示:

<Hotels>
    <Hotel />
</Hotels>
Run Code Online (Sandbox Code Playgroud)

我创建了一个List只是为了能够做到这一点的实现.我的代码如下:

[XmlRootAttribute(ElementName="Hotels")]
public class HotelList: List<HotelBasic>
Run Code Online (Sandbox Code Playgroud)

因为List保存的类没有命名,HotelHotelBasic我的xml就像

<Hotels>
   <HotelBasic />
</Hotels>
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题而不必实施ISerializableIEnumerable

aba*_*hev 26

[XmlArray("Hotels")]
[XmlArrayItem(typeof(Hotel), ElementName="Hotel")]
public HotelList[] Messages { get; set; }
Run Code Online (Sandbox Code Playgroud)

应该产生:

<Hotels>
    <Hotel />
    <Hotel />
</Hotels>
Run Code Online (Sandbox Code Playgroud)
[XmlRoot("Hotels")]
public class HotelList : IXmlSerializable
{
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        this.Hotels = XDocument.Load(reader)
                               .Select(h => new Hotel { Name = (string)h.Attribute("name") }
                               .ToList();
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotSupportedException();
    }
}
Run Code Online (Sandbox Code Playgroud)


mad*_*dd0 17

假设您正在使用XmlSerializer,如果您想要做的就是更改HotelBasic类的序列化方式,您可以使用XmlTypeAttribute:

[XmlType(TypeName = "Hotel")]
public class HotelBasic
{
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

与您的HotelList课程一起使用时,它将被序列化为:

<Hotels xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Hotel>
    <Name>One</Name>
  </Hotel>
  <Hotel>
    <Name>Two</Name>
  </Hotel>
</Hotels>
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 7

我认为madd0在这里显示了最简单的选项,但仅仅是为了完整性......我个人不推荐"将列表序列化为根对象" - 出于各种原因(包括:我看到这些属性不起作用)至少在平台上 - 可能是CF或SL,不记得了).相反,我总是建议使用自定义根类型:

[XmlRoot("Hotels")]
public class HotelResult // or something similar
{
    [XmlElement("Hotel")]
    public List<HotelBasic> Hotels { get { return hotel; } }

    private readonly List<HotelBasic> hotels = new List<HotelBasic>();
}
Run Code Online (Sandbox Code Playgroud)

这将具有相同的xml结构,并允许更大的灵活性(您可以向根添加其他属性/元素),并且不会烘焙List<T>到您的类型模型(更喜欢封装而不是继承等).