2012-01-09 11 views
14

Sto provando a generare C# che crea un frammento di XML come questo.Come si assegna un array a un attributo durante la serializzazione in C#?

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

Stavo pensando di usare qualcosa di simile:

[XmlArray("device_list"), XmlArrayItem("item")] 
public ListItem[] device_list { get; set; } 

come la proprietà, con questa dichiarazione di classe:

public class ListItem { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

che mi dà la serializzazione interna, ma I don' so come applicare l'attributo type="list" allo device_list precedente.

sto pensando (ma non è sicuro di come scrivere la sintassi) che ho bisogno di fare un:

public class DeviceList { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlArray] 
    public ListItem[] .... This is where I get lost 
} 

Aggiornato in base alle risposte di Dave

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

e l'utilizzo è attualmente :

[XmlArray("device_list"), XmlArrayItem("item")] 
public DeviceList device_list { get; set; } 

E il tipo, pur essendo dichiarato nel codice come in tal modo:

012.
device_list = new DeviceList{type = "list"} 
device_list.Add(new ListItem { type = "MAC", Value = "1234566" }); 
device_list.Add(new ListItem { type = "MAC", Value = "1234566" }); 

Non mostra il tipo sulla serializzazione. Questo è il risultato della serializzazione:

<device_list> 
    <item type="MAC">1234566</item> 
    <item type="MAC">1234566</item> 
</device_list> 

Quindi a quanto pare mi manca ancora qualcosa ...

+0

@ jcolebrand- È necessario aggiungere un attributo XmlElement alla proprietà ListType della classe DEVICELIST. Vedi il mio aggiornato di seguito. –

+0

@ jcolebrand- Ecco qualche buon riferimento su serializaton XML: http://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.80).aspx –

risposta

11

utilizzando parte della risposta di Dave sopra, ho trovato che era meglio usare la proprietà nel dichiarando classe come questa: (nota la mancanza di attributi)

public DeviceList device_list { get; set; } 

e quindi aggiornare la classe dEVICELIST simili:

[XmlType("device_list")] 
[Serializable] 
public class DeviceList { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlElement("item")] 
    public ListItem[] items { get; set; } 
} 

e mantenere la classe ListItem originale

public class ListItem { 
    [XmlAttribute] 
    public string type { get; set; } 

    [XmlText] 
    public string Value { get; set; } 
} 

e il mio serializzazione è come previsto:

<device_list type="list"> 
    <item type="MAC">1234567</item> 
    <item type="MAC">123456890</item> 
</device_list> 
+0

meravigliosamente semplice. +1 – yas4891

+0

Mi ci è voluto un po 'per capire che aggiungere l'attributo [XmlElement] è la chiave qui. Secondo MSDN: _Se si applica XmlElementAttribute a un campo o una proprietà che restituisce un array, gli elementi nell'array sono codificati come una sequenza di elementi XML. Al contrario se un XmlElementAttribute non viene applicato a tale campo o proprietà, gli elementi nell'array sono codificati come una sequenza di elementi, nidificati sotto un elemento chiamato dopo il campo o proprietà ._ – SlimShaggy

+0

Funziona alla grande. Sembra che tu possa persino applicare più riferimenti XmlElement se hai più di un tipo di bambino con lo stesso tipo genitore. – ravuya

3

Invece di utilizzare un ListItem[], derivare una nuova classe da List<T> chiamato DEVICELIST:

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

} 

Quindi, in una classe contenente utilizzare tale classe per serializzare l'XML. Il valore del tipo può essere incluso come elemento del nodo genitore, a seconda del modo in cui si configura la serializzazione. Non ricordo la sintassi esatta, ma penso che le proprietà di classe vengano aggiunte come elementi di nodo per impostazione predefinita.

classe contenente:

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

    [XmlArray("device_list"), XmlArrayItem("item")] 
    public DeviceList ListOfDevices {get;set;} 
} 
+0

quindi dove uso '[XmlArray (" device_list "), XmlArrayItem ("item")] public ListItem [] device_list {get; impostato; } "stai suggerendo che dovrei fare cosa invece? Scusa per essere denso, mi sento come se mi mancasse qualcosa qui ... – jcolebrand

+0

ListItem [] è una matrice primitiva di ListItems. Se crei una nuova classe che deriva da Lista , puoi aggiungere una nuova proprietà "tipo" a quella classe. Questo ti darà la possibilità di impostare l'elemento "tipo" nell'XML serializzato. –

+0

Aggiornato il Q, così puoi vedere cosa sto facendo e dove non vedo la serializzazione. Che cosa sto facendo di sbagliato? – jcolebrand

2

si potrebbe anche ottenere il comportamento desiderato mediante l'attuazione di [IXmlSerializable][1] nella classe contenitore:

Con il codice di seguito ottengo il seguente markup:

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

codice:

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); 
     } 
    } 
} 

Io uso il seguente codice nel mio metodo principale:

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); 
} 

Per ulteriori informazioni un'occhiata a questo tutorial here