Wie deserialisiere ich dieses XML-Dokument:
<?xml version="1.0" encoding="utf-8"?>
<Cars>
<Car>
<StockNumber>1020</StockNumber>
<Make>Nissan</Make>
<Model>Sentra</Model>
</Car>
<Car>
<StockNumber>1010</StockNumber>
<Make>Toyota</Make>
<Model>Corolla</Model>
</Car>
<Car>
<StockNumber>1111</StockNumber>
<Make>Honda</Make>
<Model>Accord</Model>
</Car>
</Cars>
Ich habe das:
[Serializable()]
public class Car
{
[System.Xml.Serialization.XmlElementAttribute("StockNumber")]
public string StockNumber{ get; set; }
[System.Xml.Serialization.XmlElementAttribute("Make")]
public string Make{ get; set; }
[System.Xml.Serialization.XmlElementAttribute("Model")]
public string Model{ get; set; }
}
.
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
[XmlArrayItem(typeof(Car))]
public Car[] Car { get; set; }
}
.
public class CarSerializer
{
public Cars Deserialize()
{
Cars[] cars = null;
string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Cars[]));
StreamReader reader = new StreamReader(path);
reader.ReadToEnd();
cars = (Cars[])serializer.Deserialize(reader);
reader.Close();
return cars;
}
}
das scheint nicht zu funktionieren :-(
Antworten:
Hier ist eine funktionierende Version. Ich habe die
XmlElementAttribute
Beschriftungen in geändert ,XmlElement
da in der XML die Werte StockNumber, Make und Model Elemente und keine Attribute sind. Außerdem habe ich das entferntreader.ReadToEnd();
(diese Funktion liest den gesamten Stream und gibt eine Zeichenfolge zurück, sodass dieDeserialize()
Funktion den Reader nicht mehr verwenden konnte ... die Position befand sich am Ende des Streams). Ich habe mir auch ein paar Freiheiten bei der Benennung genommen :).Hier sind die Klassen:
Die Deserialize-Funktion:
Und die leicht optimierte XML-Datei (ich musste ein neues Element hinzufügen, um <Cars> zu verpacken ... Net ist wählerisch beim Deserialisieren von Arrays):
quelle
[Serializable]
ist redundant bei VerwendungXmlSerializer
;XmlSerializer
prüft das einfach nie. Ebenso sind die meisten[Xml...]
Attribute redundant, da sie lediglich das Standardverhalten nachahmen. dh standardmäßig wird eine aufgerufene Eigenschaft alsStockNumber
benanntes Element gespeichert<StockNumber>
- dafür sind keine Attribute erforderlich.Wie wäre es, wenn Sie die XML-Datei einfach in einer Datei speichern und mit xsd C # -Klassen generieren?
xsd foo.xml
xsd foo.xsd /classes
Et voila - und C # -Code-Datei, die die Daten lesen kann über
XmlSerializer
:(Fügen Sie die generierten foo.cs in das Projekt ein.)
quelle
Sie haben zwei Möglichkeiten.
Methode 1. XSD- Tool
Angenommen, Sie haben Ihre XML-Datei an diesem Speicherort
C:\path\to\xml\file.xml
Sie finden sie in.
Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
Wenn Sie Windows 8 haben, können Sie einfach die Eingabeaufforderung für Entwickler in den Startbildschirm eingebencd /D "C:\path\to\xml"
xsd file.xml
xsd /c file.xsd
Und das ist es! Sie haben C # -Klassen aus der XML-Datei in generiert
C:\path\to\xml\file.cs
Methode 2 - Spezial einfügen
Erforderliches Visual Studio 2012+
Edit > Paste special > Paste XML As Classes
Und das ist es!
Verwendungszweck
Die Verwendung dieser Hilfsklasse ist sehr einfach:
Jetzt müssen Sie nur noch Folgendes tun:
quelle
Paste XML As Classes
Befehl zielt jedoch nur auf .NET 4.5 abDas folgende Snippet sollte den Trick ausführen (und Sie können die meisten Serialisierungsattribute ignorieren):
...
quelle
Sehen Sie, ob dies hilft:
.
Wenn dies nicht der Fall ist, verwenden Sie das mit Visual Studio gelieferte Programm xsd.exe, um ein Schemadokument basierend auf dieser XML-Datei zu erstellen, und verwenden Sie es dann erneut, um eine Klasse basierend auf dem Schemadokument zu erstellen.
quelle
Ich denke nicht, dass .net "wählerisch beim Deserialisieren von Arrays" ist. Das erste XML-Dokument ist nicht gut geformt. Es gibt kein Wurzelelement, obwohl es so aussieht. Das kanonische XML-Dokument hat einen Stamm und mindestens 1 Element (wenn überhaupt). In Ihrem Beispiel:
quelle
Versuchen Sie diesen Codeblock, wenn Ihre XML-Datei irgendwo auf der Festplatte generiert wurde und wenn Sie Folgendes verwendet haben
List<T>
:Hinweis:
C:\serialize.xml
ist der Pfad meiner XML-Datei. Sie können es für Ihre Bedürfnisse ändern.quelle
Kevins Antwort ist gut, abgesehen von der Tatsache, dass Sie in der realen Welt häufig nicht in der Lage sind, das ursprüngliche XML an Ihre Bedürfnisse anzupassen.
Es gibt auch eine einfache Lösung für das ursprüngliche XML:
Und dann können Sie einfach anrufen:
quelle
Probieren Sie diese generische Klasse für XML-Serialisierung und -Deserialisierung aus.
quelle
Für Anfänger
Ich fand die Antworten hier sehr hilfreich, das heißt, ich hatte immer noch (nur ein bisschen) Mühe, dies zum Laufen zu bringen. Falls es jemandem hilft, werde ich die funktionierende Lösung formulieren:
XML aus der Originalfrage. Die XML befindet sich in einer Datei Class1.xml. Eine
path
zu dieser Datei wird im Code verwendet, um diese XML-Datei zu finden.Ich habe die Antwort von @erymski verwendet, um dies zum Laufen zu bringen. Deshalb habe ich eine Datei namens Car.cs erstellt und Folgendes hinzugefügt:
Der andere Code von @erymski ...
... geht in Ihr Hauptprogramm (Program.cs)
static CarCollection XCar()
wie folgt :Ich hoffe es hilft :-)
quelle
Wie wäre es mit einer generischen Klasse zum Deserialisieren eines XML-Dokuments?
Dieser Teil kann erforderlich sein oder nicht. Öffnen Sie das XML-Dokument in Visual Studio, klicken Sie mit der rechten Maustaste auf das XML und wählen Sie Eigenschaften. Wählen Sie dann Ihre Schemadatei.
quelle
Einzeiler:
quelle
Die Idee ist, dass alle Ebenen für die Deserialisierung behandelt werden. Bitte sehen Sie sich eine Beispiellösung an, die mein ähnliches Problem gelöst hat
Das obige XML wird in zwei Ebenen behandelt
Die innere Ebene
Auf die gleiche Weise benötigen Sie mehrere Ebenen mit
car as array
Überprüfen Sie dieses Beispiel auf mehrstufige Deserialisierungquelle
Wenn beim Erstellen Ihrer xsd-Datei mit xsd.exe Fehler auftreten, verwenden Sie die in msdn angegebene XmlSchemaInference-Klasse . Hier ist ein Unit-Test, um zu demonstrieren:
quelle
Sie können nur ein Attribut für Ihre Cars-Autoeigenschaft von XmlArrayItem in XmlElment ändern. Das heißt, von
zu
quelle
Meine Lösung:
Edit > Past Special > Paste XML As Classes
diese Option , um die Klasse in Ihren Code aufzunehmenList<class1
>) undXmlSerializer
serialisieren Sie diese Liste mit einer in einexml
Datei.deserialize
es.Code:
HINWEIS: Sie müssen auf den Stammnamen achten, ändern Sie ihn nicht. Meins ist "ArrayOfClass1"
quelle
quelle