2011-10-28 12 views
5

Mam następującą strukturę XML. Element theElement może zawierać theOptionalList element, czy nie:Jak ozdobić/zdefiniować elementy klasy dla opcjonalnego elementu XML do użycia z XmlSerializer?

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

Co to czysty sposób wyrazić odpowiedniej struktury klasowej?

jestem całkiem pewny, co następuje:

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

Jak również:

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

Ale co do theElement? Czy biorę element theOptionalList jako typ tablicowy, aby czytał, co znajduje się w pliku (nic lub jedno), a następnie sprawdzał kod, czy istnieje? Czy jest jeszcze inny dekorator, który mogę dostarczyć? Czy to po prostu działa?

EDIT: Skończyło się na wykorzystaniu informacji z this answer.

Odpowiedz

5

spróbuj dodać IsNullable = true do atrybutu XmlArrayItem.

+0

Dzięki za odpowiedź James. Zgaduję, że poradziłoby to z elementem 'theOptionalList' bez elementów, ale czy obsługiwałoby' TheOptionalList' w ogóle nieistniejącą? (Może nie rozumiem, co sugerujesz.) Ponadto nie ma schematu dla mojego formatu; to wszystko przez ustną umowę między mną a innym deweloperem.:) – John

+0

Nie jestem pozytywny, ale myślę, że użycie 'IsNullable' spowoduje wykluczenie go, jeśli tablica ma wartość NULL. –

+1

Rozważ schemat. Jest bardzo przydatny, jednak mały i jest świetnym elementem dla twojego "zestawu narzędzi". – Gusdor

4

Wygląda na to, że można użyć innego parametru bool, aby podać element lub nie.

Inną opcją jest użycie specjalnego wzoru, aby stworzyć logiczną pole rozpoznany przez XmlSerializer i zastosować XmlIgnoreAttribute pola. Wzór jest tworzony w postaci propertyNameSpecified. Na przykład, jeśli istnieje pole o nazwie "MojaFirstName", należy również utworzyć pole o nazwie "MyFirstNameSpecified", które instruuje XmlSerializer, czy do wygenerować element XML o nazwie "MyFirstName". Zostało to pokazane w następującym przykładzie: .

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

Dzięki za odpowiedź. Ten przykład dotyczy serializacji, która jest częścią tego, z czym mam do czynienia. Druga część to deserializacja. Co się stanie, gdy wywołasz funkcję "Deserialize()" w pliku o tym formacie? Ponieważ nie sądzę, mogę powiedzieć "XmlSerializer" dla pliku jako całości, czego można się spodziewać po elemencie. Innymi słowy, czy istnieje domyślne zachowanie, jeśli deserializuję i nie widzę elementu określonego w klasie? – John

+0

Tak, istnieje domyślne zachowanie: Domyślny konstruktor klasy. Kiedy deserializujesz swój XML, 'XMLSerializer' wywołuje domyślny konstruktor, aby utworzyć twoje obiekty, abyś mógł ustawić tutaj swoje ustawienia domyślne. Ogólnie pomocne jest ustawienie wartości domyślnych dla właściwości w domyślnym contructor i dodanie ': this()' na innych konstruktorach, aby zapewnić, że twoje wartości domyślne zostaną ustawione jako pierwsze. – JCH2k

0

dodatkowy do własności XxySpecifed, istnieje również metoda z ShouldSerialize prefiksu

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

public bool ShouldSerializeOptionaXyz() { 
    return OptionalXyz != null && OptionalXyz.Count > 0 ; 
} 
Powiązane problemy