Deserialisieren des leeren XML-Attributwerts in die Nullable Int-Eigenschaft mithilfe von XmlSerializer
Bekomme ich eine xml von der 3rd-party und ich brauche deserialisiert werden es in C# - Objekt. Dieses xml kann enthalten Attribute mit Wert vom Typ integer oder leerer Wert: attr="11" oder attr="". Ich möchte Deserialisieren dieses Attribut mit dem Wert in der Eigenschaft mit Typ nullable-integer. Aber XmlSerializer nicht unterstützt Deserialisierung in nullable-Typen. Die folgenden test-code schlägt fehl, während der Erstellung des XmlSerializer mit InvalidOperationException {"Es war ein Fehler reflektieren Typ 'TestConsoleApplication.SerializeMe'."}.
[XmlRoot("root")]
public class SerializeMe
{
[XmlElement("element")]
public Element Element { get; set; }
}
public class Element
{
[XmlAttribute("attr")]
public int? Value { get; set; }
}
class Program {
static void Main(string[] args) {
string xml = "<root><element attr=''>valE</element></root>";
var deserializer = new XmlSerializer(typeof(SerializeMe));
Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
var result = (SerializeMe)deserializer.Deserialize(xmlStream);
}
}
Wenn ich den Typ 'Value' - Eigenschaft auf int, Deserialisierung schlägt fehl mit InvalidOperationException:
Es ist ein Fehler in XML Dokument (1, 16).
Kann jemand beraten, wie Deserialisieren Attribut mit einem leeren Wert in nullable-Typ (als null) in der gleichen Zeit zu Deserialisieren nicht-leere Attribut-Wert in der integer? Gibt es irgendeinen trick, damit ich nicht zu tun haben Deserialisierung jedes Feld manuell (tatsächlich gibt es eine Menge von Ihnen)?
Update nach dem Kommentar von ahsteele:
-
Soweit ich weiß, wird dieses Attribut funktioniert nur mit XmlElementAttribute - dieses Attribut gibt an, dass das element keinen Inhalt hat, ob child-Elemente oder text. Aber ich muss die Lösung für XmlAttributeAttribute. Trotzdem kann ich nicht ändern, xml, denn ich habe keine Kontrolle über Sie.
-
Diese Eigenschaft funktioniert nur, wenn der Attributwert ist nicht leer oder wenn kein Attribut vorhanden ist. Wenn attr hat einen leeren Wert (attr=") die XmlSerializer-Konstruktor fehl (wie erwartet).
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; }
-
Benutzerdefinierte Nullable-Klasse, wie in diesem blog-post von Alex Scordellis
Habe ich versucht zu verabschieden, die die Klasse von diesem blog-post zu meinem problem:
[XmlAttribute("attr")] public NullableInt Value { get; set; }
Aber XmlSerializer-Konstruktor scheitert mit InvalidOperationException:
Nicht serialisieren Mitglied der 'Wert' des Typs TestConsoleApplication.NullableInt.
XmlAttribute/XmlText kann nicht verwendet werden zum codieren Arten IXmlSerializable implementieren }
-
Hässlich Surrogat-Lösung (Schande über mich, dass ich schrieb diesen code hier 🙂 ):
public class Element { [XmlAttribute("attr")] public string SetValue { get; set; } public int? GetValue() { if ( string.IsNullOrEmpty(SetValue) || SetValue.Trim().Length <= 0 ) return null; int result; if (int.TryParse(SetValue, out result)) return result; return null; } }
Aber ich will nicht zu kommen mit die Lösung wie diese, weil es bricht Schnittstelle meiner Klasse für seine Verbraucher. Ich würde besser manuell IXmlSerializable-Schnittstelle implementieren.
So wie es derzeit aussieht muss ich IXmlSerializable implementieren für die ganze Element Klasse (es ist groß), und es gibt keine einfache Lösung...
InformationsquelleAutor der Frage Aliaksei Kliuchnikau | 2009-08-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollte dies funktionieren:
InformationsquelleAutor der Antwort
Löste ich dieses problem durch die Implementierung von IXmlSerializable-Schnittstelle. Ich habe nicht gefunden, einfacher Weg.
Hier ist der test-code-Beispiel:
InformationsquelleAutor der Antwort Aliaksei Kliuchnikau
Ich ve wurde Herumspielen mit Serialisierung selber viel spät und haben festgestellt, die folgenden Artikel und Beiträge hilfreich beim Umgang mit null-Daten für Wert-Typen.
Die Antwort auf Wie man einen Werttyp, der null zulässt mit XmlSerializer in C# - Serialisierung details eine ziemlich raffinierte trick mit dem XmlSerializer. Insbesondere die XmlSerialier sieht für ein XXXSpecified Boolesche Eigenschaft, um festzustellen, ob es aufgenommen werden sollte, die Ihnen erlaubt zu ignorieren null-Werte.
Alex Scordellis fragte einer StackOverflow-Frage, die erhalten eine gute Antwort. Alex hat auch einen guten Kommentar auf seinem blog über das problem versuchte er zu lösen Mit XmlSerializer zu Deserialisieren in einen Nullable<int>.
In der MSDN-Dokumentation auf Xsi:nil-Attribut-Bindung Unterstützen ist auch nützlich. Wie ist die Dokumentation auf IXmlSerializable-Schnittstellewenn das schreiben Ihrer eigenen Implementierung sollte Ihre Letzte Ausweg.
InformationsquelleAutor der Antwort ahsteele
Dachte, ich könnte genauso gut werfen meine Antwort in den Hut:
Gelöst wird dieses Problem durch die Erstellung einer benutzerdefinierten Typ, die die IXmlSerializable-Schnittstelle:
Sagen wir, Sie haben ein XML-Objekt mit den folgenden Knoten:
Dem Objekt um Sie zu vertreten:
Dynamische nullable-Struktur zu repräsentieren, potenzielle nullable-Einträge, zusammen mit der Konvertierung
InformationsquelleAutor der Antwort Levi Fuller