Как я могу присвоить массив атрибуту во время сериализации в С#?
Я пытаюсь создать С#, который создает фрагмент XML, как это.
<device_list type="list">
<item type="MAC">11:22:33:44:55:66:77:88</item>
<item type="MAC">11:22:33:44:55:66:77:89</item>
<item type="MAC">11:22:33:44:55:66:77:8A</item>
</device_list>
Я думал использовать что-то вроде этого:
[XmlArray( "device_list" ), XmlArrayItem("item")]
public ListItem[] device_list { get; set; }
как свойство, с этим объявлением класса:
public class ListItem {
[XmlAttribute]
public string type { get; set; }
[XmlText]
public string Value { get; set; }
}
Что дает мне внутреннюю сериализацию, но я не знаю, как применить атрибут type="list"
к device_list
выше.
Я думаю (но не уверен, как писать синтаксис), что мне нужно сделать:
public class DeviceList {
[XmlAttribute]
public string type { get; set; }
[XmlArray]
public ListItem[] .... This is where I get lost
}
Обновлено на основе ответов Дейва
public class DeviceList : List<ListItem> {
[XmlAttribute]
public string type { get; set; }
}
public class ListItem {
[XmlAttribute]
public string type { get; set; }
[XmlText]
public string Value { get; set; }
}
и использование в настоящее время:
[XmlArray( "device_list" ), XmlArrayItem("item")]
public DeviceList device_list { get; set; }
И тип, будучи объявленным в коде следующим образом:
device_list = new DeviceList{type = "list"}
device_list.Add( new ListItem { type = "MAC", Value = "1234566" } );
device_list.Add( new ListItem { type = "MAC", Value = "1234566" } );
Не отображается тип сериализации. Это результат сериализации:
<device_list>
<item type="MAC">1234566</item>
<item type="MAC">1234566</item>
</device_list>
Так что, видимо, я все еще что-то пропустил...
Ответы
Ответ 1
Используя часть ответа Дэйва выше, я обнаружил, что лучше всего использовать свойство в объявляющем классе следующим образом: (обратите внимание на отсутствие атрибутов)
public DeviceList device_list { get; set; }
а затем обновите класс DeviceList следующим образом:
[XmlType("device_list")]
[Serializable]
public class DeviceList {
[XmlAttribute]
public string type { get; set; }
[XmlElement( "item" )]
public ListItem[] items { get; set; }
}
и сохраните исходный класс ListItem
public class ListItem {
[XmlAttribute]
public string type { get; set; }
[XmlText]
public string Value { get; set; }
}
и моя сериализация будет такой, как ожидалось:
<device_list type="list">
<item type="MAC">1234567</item>
<item type="MAC">123456890</item>
</device_list>
Ответ 2
Вместо использования ListItem[]
выведите новый класс из List<T>
, называемый DeviceList:
public class DeviceList : List<ListItem>
{
[XmlElement(ElementName = "type")]
public string ListType {get;set;}
}
Затем в содержащем классе используйте этот класс для сериализации XML. Значение типа может быть включено как элемент родительского node, в зависимости от способа настройки сериализации. Я не помню точный синтаксис, но я думаю, что свойства класса добавляются как элементы node по умолчанию.
Содержит класс:
public class SerializeMyStuff
{
public SeriazlieMyStuff()
{
ListOfDevices = new DeviceList();
ListOfDevices.ListType = "list";
}
[XmlArray( "device_list" ), XmlArrayItem("item")]
public DeviceList ListOfDevices {get;set;}
}
Ответ 3
Вы также можете добиться желаемого поведения, реализовав [IXmlSerializable][1]
в своем классе контейнера:
В приведенном ниже коде я получаю следующую разметку:
<?xml version="1.0"?>
<DeviceList type="list">
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:88</Item>
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:89</Item>
<Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="MAC">11:22:33:44:55:66:77:8A</Item>
</DeviceList>
код:
public class Item
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlText]
public string Value { get; set; }
}
public class DeviceList : IXmlSerializable
{
public string Type { get; set; }
public List<Item> Items { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
reader.MoveToContent();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString("type", Type);
XmlSerializer serializer = new XmlSerializer(typeof(Item));
foreach (var item in Items)
{
serializer.Serialize(writer, item);
}
}
}
В основном методе я использую следующий код:
var dlist = new DeviceList
{
Type = "list",
Items = new List<Item>
{
new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:88"},
new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:89"},
new Item {Type = "MAC", Value = "11:22:33:44:55:66:77:8A"},
}
};
using(FileStream stream = new FileStream(@"D:\jcoletest.xml", FileMode.Create, FileAccess.Write))
{
new XmlSerializer(typeof (DeviceList)).Serialize(stream, dlist);
}
Подробнее см. здесь