2011-10-28 11 views
5

Ho la seguente struttura XML. L'elemento theElement può contenere theOptionalList elemento, o no:Come decorare/definire i membri della classe per un elemento XML facoltativo da utilizzare con XmlSerializer?

<theElement attrOne="valueOne" attrTwo="valueTwo"> 
    <theOptionalList> 
     <theListItem attrA="valueA" /> 
     <theListItem attrA="anotherValue" /> 
     <theListItem attrA="stillAnother" /> 
    </theOptionalList> 
</theElement> 
<theElement attrOne="anotherOne" attrTwo="anotherTwo" /> 

Che cosa è un modo pulito per esprimere la struttura corrispondente classe?

Sono abbastanza sicuro di quanto segue:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 

namespace MyNamespace 
{ 
    public class TheOptionalList 
    { 
     [XmlAttributeAttribute("attrOne")] 
     public string AttrOne { get; set; } 

     [XmlAttributeAttribute("attrTwo")] 
     public string AttrTwo { get; set; } 

     [XmlArrayItem("theListItem", typeof(TheListItem))] 
     public TheListItem[] theListItems{ get; set; } 

     public override string ToString() 
     { 
      StringBuilder outText = new StringBuilder(); 

      outText.Append("attrOne = " + AttrOne + " attrTwo = " + AttrTwo + "\r\n"); 

      foreach (TheListItem li in theListItems) 
      { 
       outText.Append(li.ToString()); 
      } 

      return outText.ToString(); 
     } 
    } 
} 

Così come:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Serialization; 

namespace MyNamespace 
{ 
    public class TheListItem 
    { 
     [XmlAttributeAttribute("attrA")] 
     public string AttrA { get; set; } 

     public override string ToString() 
     { 
      StringBuilder outText = new StringBuilder(); 

      outText.Append(" attrA = " + AttrA + "\r\n");     
      return outText.ToString(); 
     } 
    } 
} 

Ma che dire per theElement? Prendo l'elemento theOptionalList come un tipo di matrice per fare in modo che legga ciò che trova nel file (nulla o uno) e poi controlla nel codice se è lì o no? O c'è un altro decoratore che posso fornire? Oppure funziona?

MODIFICA: Ho finito per utilizzare le informazioni da this answer.

risposta

5

Prova ad aggiungere IsNullable = true all'attributo XmlArrayItem.

+0

Grazie per la risposta James. Immagino che questo gestisca un elemento 'theOptionalList' senza elementi, ma gestirà' theOptionalList' che non esiste affatto? (Forse non capisco cosa stai suggerendo.) Inoltre, non c'è schema per il mio formato; è tutto per accordo verbale tra me e un altro sviluppatore.:) – John

+0

Non sono positivo, ma penso che l'uso di 'IsNullable' lo escluderebbe se l'array è nullo. –

+1

Considera uno schema. È potentemente utile, per quanto piccolo, ed è un ottimo pezzo per il tuo "toolkit". – Gusdor

4

Sembra che sia possibile utilizzare un altro bool per specificare di includere un elemento o meno.

Un'altra opzione è quella di utilizzare un modello speciale per creare un campo booleano riconosciuto dal XmlSerializer, e di applicare il XmlIgnoreAttribute al campo. Il modello viene creato sotto forma di propertyNameSpecified. Ad esempio, se esiste un campo denominato "MyFirstName", verrà creato anche un campo denominato "MyFirstNameSpecified" che indica a XmlSerializer se a generare l'elemento XML denominato "MyFirstName". Questo è mostrato nell'esempio seguente .

public class OptionalOrder 
{ 
    // This field should not be serialized 
    // if it is uninitialized. 
    public string FirstOrder; 

    // Use the XmlIgnoreAttribute to ignore the 
    // special field named "FirstOrderSpecified". 
    [System.Xml.Serialization.XmlIgnoreAttribute] 
    public bool FirstOrderSpecified; 
} 

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

+0

Grazie per la risposta. Questo esempio riguarda la serializzazione, che è parte di ciò che sto affrontando. L'altra parte è la deserializzazione. Cosa succede se chiamo 'Deserialize()' su un file con questo formato? Perché non penso di poter dire a 'XmlSerializer' per il file nel suo insieme cosa aspettarsi per elemento. In altre parole, esiste un comportamento predefinito se si deserializza e non viene visualizzato un membro specificato nella classe? – John

+0

Sì, esiste un comportamento predefinito: il costruttore predefinito della classe. Quando deserializzi il tuo XML, 'XMLSerializer' chiama il costruttore predefinito per creare i tuoi oggetti, quindi puoi settare i tuoi valori di default qui. In genere è utile impostare valori predefiniti per le proprietà nel contructor di default e aggiungere ': this()' sugli altri costruttori per assicurarsi che i valori di default siano impostati per primi. – JCH2k

0

supplementare alla proprietà XxySpecifed, v'è anche un metodo con un ShouldSerialize prefisso

[XmlElement] 
public List<string> OptionalXyz {get; set;} 

public bool ShouldSerializeOptionaXyz() { 
    return OptionalXyz != null && OptionalXyz.Count > 0 ; 
} 
Problemi correlati