2008-11-03 3 views
14

Ich verwende XmlSerializer, um ein Objekt in C# zu schreiben und zu lesen. Ich benutze derzeit die Attribute XmlElement und XmlIgnore, um die Serialisierung des Objekts zu manipulieren.Kann ich nicht mit XmlSerializer in C# deserialisieren, wenn ein Element nicht gefunden wird?

Wenn meine XML-Datei ein XML-Element fehlt, das ich benötige, wird mein Objekt immer noch deserialisiert (XML -> Objekt). Wie gebe ich (vorzugsweise über Attribute) an, dass ein bestimmtes Feld "benötigt" ist?

Hier ist ein Beispiel-Methode von dem, was ich bin derzeit mit:

[XmlElement(ElementName="numberOfWidgets")] 
public int NumberThatIsRequired { 
    set ...; 
    get ...; 
} 

Meine ideale Lösung so etwas wie ein XmlRequired Attribut hinzuzufügen wäre.

Gibt es auch eine gute Referenz für welche Attribute verfügbar sind, um das Verhalten von XmlSerializer zu manipulieren?

+0

Ähnliche msdn Frage [hier] (http://social.msdn.microsoft.com/Forums/eu/xmlandnetfx/thread/a134471c-6b20-433e-8dd4-d153cac29810), die auch erklärt, dass Validierung ist, was Sie versuchen zu tun – KCD

+0

Wenn Sie nicht das Element 'numberOfWidgets' in der XML haben, was haben Sie in der Eigenschaft NumberThatIsRequired? Null? –

Antwort

4

Ich habe eine Antwort für den zweiten Teil: "Attributes that control XML serialization".

noch den ersten Teil ... Untersuchung

EDIT: Ich vermute stark, Sie dies selbst durch XML-Deserialisierung nicht tun können. Ich habe gerade xsd.exe auf einem Beispielschema ausgeführt, das ein erforderliches Attribut enthält - und es ist genau dasselbe, wenn das Attribut als optional markiert ist. Wenn es eine Möglichkeit geben würde, Eigenschaften festzulegen, würde ich erwarten, dass sie in diesem Fall implementiert wird.

Ich vermute, Sie müssen im Grunde nur Ihren Baum von Objekten validieren, nachdem Sie ihn deserialisiert haben. Sorry über das ...

+0

Sie müssen einen XML-Namespace ordnungsgemäß in Ihrer Quell-XML einrichten, der auch in Ihrer XSD referenziert wird, oder die Validierung mit einer XSD funktioniert nicht ordnungsgemäß, einschließlich der erforderlichen Feldüberprüfung. –

15

Die einzige Möglichkeit, die ich gefunden habe, ist über XSD. Was Sie tun können, ist zu validieren, während Sie deserialisieren:

static T Deserialize<T>(string xml, XmlSchemaSet schemas) 
{ 
    //List<XmlSchemaException> exceptions = new List<XmlSchemaException>(); 
    ValidationEventHandler validationHandler = (s, e) => 
    { 
     //you could alternatively catch all the exceptions 
     //exceptions.Add(e.Exception); 
     throw e.Exception; 
    }; 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.Schemas.Add(schemas); 
    settings.ValidationType = ValidationType.Schema; 
    settings.ValidationEventHandler += validationHandler; 

    XmlSerializer serializer = new XmlSerializer(typeof(T)); 
    using (StringReader sr = new StringReader(xml)) 
     using (XmlReader books = XmlReader.Create(sr, settings)) 
      return (T)serializer.Deserialize(books); 
} 
4

Für Erweiterbarkeit Gründen XmlSerializer ist sehr nachsichtig, wenn es um die Deserialisierung kommt; Dinge wie [DefaultValue], ShouldSerialize{Foo} und {Foo}Specified sind hauptsächlich während Serialisierung (Ausnahme {Foo}Specified wird, die während der Deserialisierung sowie abgefragt während der Serialisierung eingestellt ist) verwendet.

als solche; Es gibt keine einfache Möglichkeit, dies zu tun, es sei denn, Sie implementieren IXmlSerializable und tun es selbst. damagednoob zeigt eine Option xsd, die auch eine Option ist.

+1

DefaultValue hat mindestens einen wichtigen Effekt während der Deserialisierung. Wenn das Element leer ist, ohne DefaultValue, kann ein Parsing-Fehler vorliegen. Der [generierte Code] (http://msdn.microsoft.com/en-us/library/aa302290.aspx) überspringt jedoch das leere Element. –

Verwandte Themen