Как дать массиву атрибут во время сериализации в C #? - PullRequest
15 голосов
/ 09 января 2012

Я пытаюсь сгенерировать C #, который создает фрагмент 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>

Так, очевидно, я все еще что-то упускаю ...

Ответы [ 3 ]

12 голосов
/ 09 января 2012

Используя часть ответа Дэйва выше, я обнаружил, что лучше всего использовать свойство в объявленном классе следующим образом: (обратите внимание на отсутствие атрибутов)

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>
4 голосов
/ 09 января 2012

Вместо использования ListItem[], выведите новый класс из List<T> с именем DeviceList:

public class DeviceList : List<ListItem>
{
   [XmlElement(ElementName = "type")]
   public string ListType {get;set;}

}

Затем в содержащем классе используйте этот класс для сериализации XML.Значение типа может быть включено в качестве элемента родительского узла в зависимости от способа настройки сериализации.Я не помню точный синтаксис, но я думаю, что свойства класса добавляются как элементы узла по умолчанию.

Содержащий класс:

public class SerializeMyStuff
{
   public SeriazlieMyStuff()
   {
       ListOfDevices = new DeviceList();
       ListOfDevices.ListType = "list";
   }

   [XmlArray( "device_list" ), XmlArrayItem("item")]
   public DeviceList ListOfDevices {get;set;}
}
3 голосов
/ 09 января 2012

Вы также можете достичь желаемого поведения, реализовав [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);
}

Для получения дополнительной информации посмотрите этот учебник здесь

...