2009-09-06 16 views
5

Ho un file XML guardando un po 'come questo:Implementazione IXmlSerializable su un oggetto di collezione

<xml> 
    <A>value</A> 
    <B>value</B> 
    <listitems> 
    <item> 
     <C>value</C> 
     <D>value</D> 
    </item> 
    </listitems> 
</xml> 

e ho una due oggetti che rappresentano questo xml:

class XmlObject 
{ 
    public string A { get; set; } 
    public string B { get; set; } 
    List<Item> listitems { get; set; } 
} 

class Item : IXmlSerializable 
{ 
    public string C { get; set; } 
    public string D { get; set; } 

    //Implemented IXmlSerializeable read/write 
    public void ReadXml(System.Xml.XmlReader reader) 
    { 
    this.C = reader.ReadElementString(); 
    this.D = reader.ReadElementString(); 
    } 
    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
    writer.WriteElementString("C", this.C); 
    writer.WriteElementString("D", this.D); 
    } 
} 

uso il XmlSerializer per serializzare/deserializzare XmlObject in un file.

Il problema è che quando ho implementato le funzioni personalizzate IXmlSerializable sul mio oggetto "oggetto secondario", ottengo sempre un elemento (il primo) nella mia raccolta XmlObject.listitems durante la deserializzazione del file. Se rimuovo: IXmlSerializable tutto funziona come previsto.

Cosa faccio di sbagliato?

Modifica: ho implementato IXmlSerializable.GetSchema e ho bisogno di utilizzare IXmlSerializable sul mio "oggetto figlio" per eseguire alcune trasformazioni del valore personalizzato.

risposta

2

modificare il codice in questo modo:

public void ReadXml(System.Xml.XmlReader reader) 
    { 
     reader.Read(); 
     this.C = reader.ReadElementString(); 
     this.D = reader.ReadElementString(); 
     reader.Read(); 
    } 

Per prima cosa è saltare l'inizio del nodo Oggetto, leggere le due stringhe, quindi leggere oltre il nodo finale in modo che il lettore si trovi nella posizione corretta. Questo leggerà tutti i nodi nella matrice.

È necessario prestare attenzione quando si modifica xml da soli :)

+0

Grazie mille. –

1

Non è necessario utilizzare IXmlSerializable. Ma se vuoi, devi implementare il metodo GetShema(). Dopo qualche codice di modifica che funziona sembra che:

[XmlRoot("XmlObject")] 
public class XmlObject 
{ 
    [XmlElement("A")] 
    public string A { get; set; } 
    [XmlElement("B")] 
    public string B { get; set; } 
    [XmlElement("listitems")] 
    public List<Item> listitems { get; set; } 
} 

public class Item : IXmlSerializable 
{ 
    [XmlElement("C")] 
    public string C { get; set; } 
    [XmlElement("D")] 
    public string D { get; set; } 

    #region IXmlSerializable Members 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     this.C = reader.ReadElementString(); 
     this.D = reader.ReadElementString(); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     writer.WriteElementString("C", this.C); 
     writer.WriteElementString("D", this.D); 
    } 

    #endregion 
} 

Risultati per 2 articoli in ITEMLIST sarà simile a quanto segue:

<?xml version="1.0" encoding="utf-8"?> 
<XmlObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <A>value</A> 
    <B>value</B> 
    <listitems> 
    <C>value0</C> 
    <D>value0</D> 
    </listitems> 
    <listitems> 
    <C>value1</C> 
    <D>value1</D> 
    </listitems> 
</XmlObject> 
+0

Ciò non ha cambiato nulla. Ma grazie per aver provato. –

Problemi correlati