Как установить имя элемента XmlArrayItem для реализации List <Custom>?
Я хочу создать пользовательскую структуру XML следующим образом:
<Hotels>
<Hotel />
</Hotels>
Я создал реализацию List
, чтобы это сделать. Мой код выглядит следующим образом:
[XmlRootAttribute(ElementName="Hotels")]
public class HotelList: List<HotelBasic>
Поскольку класс, который выполняется List, не указан Hotel
, но HotelBasic
мой xml похож на
<Hotels>
<HotelBasic />
</Hotels>
Как исправить это, не выполняя ISerializable
или IEnumerable
?
Ответы
Ответ 1
Предполагая, что вы используете XmlSerializer
, если все, что вы хотите сделать, - это изменить способ сериализации класса HotelBasic
, вы можете использовать XmlTypeAttribute
:
[XmlType(TypeName = "Hotel")]
public class HotelBasic
{
public string Name { get; set; }
}
При использовании с вашим классом 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>
Ответ 2
[XmlArray("Hotels")]
[XmlArrayItem(typeof(Hotel), ElementName="Hotel")]
public HotelList[] Messages { get; set; }
должен производить:
<Hotels>
<Hotel />
<Hotel />
</Hotels>
[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();
}
}
Ответ 3
Я думаю, 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>();
}
Это будет иметь одну и ту же структуру xml и даст большую гибкость (вы можете добавить другие атрибуты/элементы в корневой каталог) и не испеките List<T>
в модель вашего типа (предпочитайте инкапсуляцию по наследованию и т.д.).