Deserialisieren von XML-Dokumenten

472

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 :-(

Alex
quelle
Ich denke, Sie müssen den spitzen Klammern in Ihrem Beispieldokument entkommen.
Harpo
4
Diese Antwort ist wirklich sehr, sehr gut: stackoverflow.com/a/19613934/196210
Revious

Antworten:

359

Hier ist eine funktionierende Version. Ich habe die XmlElementAttributeBeschriftungen in geändert , XmlElementda in der XML die Werte StockNumber, Make und Model Elemente und keine Attribute sind. Außerdem habe ich das entfernt reader.ReadToEnd();(diese Funktion liest den gesamten Stream und gibt eine Zeichenfolge zurück, sodass die Deserialize()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:

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement("StockNumber")]
    public string StockNumber { get; set; }

    [System.Xml.Serialization.XmlElement("Make")]
    public string Make { get; set; }

    [System.Xml.Serialization.XmlElement("Model")]
    public string Model { get; set; }
}


[Serializable()]
[System.Xml.Serialization.XmlRoot("CarCollection")]
public class CarCollection
{
    [XmlArray("Cars")]
    [XmlArrayItem("Car", typeof(Car))]
    public Car[] Car { get; set; }
}

Die Deserialize-Funktion:

CarCollection cars = null;
string path = "cars.xml";

XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));

StreamReader reader = new StreamReader(path);
cars = (CarCollection)serializer.Deserialize(reader);
reader.Close();

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):

<?xml version="1.0" encoding="utf-8"?>
<CarCollection>
<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>
</CarCollection>
Kevin Tighe
quelle
68
Das [Serializable]ist redundant bei Verwendung XmlSerializer; XmlSerializerprüft das einfach nie. Ebenso sind die meisten [Xml...]Attribute redundant, da sie lediglich das Standardverhalten nachahmen. dh standardmäßig wird eine aufgerufene Eigenschaft als StockNumberbenanntes Element gespeichert <StockNumber>- dafür sind keine Attribute erforderlich.
Marc Gravell
3
Beachten Sie, dass XmlElementAttribute = XmlElement (es ist eine Sprachfunktion, bei der Sie das Suffix "Attribut" weglassen können). Eine echte Lösung besteht darin, den Aufruf ReadToEnd () zu entfernen und einen Stammknoten hinzuzufügen. Aber verwenden Sie besser den Code von Erymski, der die Frage löst (analysieren Sie die angegebene XML)
Flamefire
2
Danke Kevin, aber was ist, wenn ich die CarsCollection aus dem Beispiel-XML entfernt habe? Ich habe Carscollection aus Klassen entfernt und Code deserealisiert, aber es ist mir nicht gelungen.
Vikrant
441

Wie wäre es, wenn Sie die XML-Datei einfach in einer Datei speichern und mit xsd C # -Klassen generieren?

  1. Schreiben Sie die Datei auf die Festplatte (ich habe sie foo.xml genannt)
  2. Generieren Sie die xsd: xsd foo.xml
  3. Generieren Sie das C #: xsd foo.xsd /classes

Et voila - und C # -Code-Datei, die die Daten lesen kann über XmlSerializer:

    XmlSerializer ser = new XmlSerializer(typeof(Cars));
    Cars cars;
    using (XmlReader reader = XmlReader.Create(path))
    {
        cars = (Cars) ser.Deserialize(reader);
    }

(Fügen Sie die generierten foo.cs in das Projekt ein.)

Marc Gravell
quelle
6
Du bist der Mann! Vielen Dank. Für jeden, der es benötigt, kann "Pfad" ein Stream sein, den Sie aus einer Webantwort wie folgt erstellen: var resp = response.Content.ReadAsByteArrayAsync (); var stream = neuer MemoryStream (bzw. Ergebnis);
Induster
1
Tolle Idee, aber für mein etwas komplizierteres Modell mit mehreren verschachtelten Arrays konnte es nicht richtig funktionieren. Ich bekam immer wieder Fehler bei der Typkonvertierung für die verschachtelten Arrays - und das generierte Namensschema ließ zu wünschen übrig. Deshalb bin ich den benutzerdefinierten Weg gegangen.
GotDibbs
9
Wie komme ich zu xsd.exe
jwillmer
2
xsd.exe ist an der Visual Studio-Eingabeaufforderung verfügbar, nicht an der Windows-Eingabeaufforderung. Überprüfen Sie, ob Sie die Eingabeaufforderung in Visual Studio unter Extras öffnen können. Wenn nicht, versuchen Sie, über den Visual Studio-Ordner darauf zuzugreifen. Für VS 2012 befand es sich hier: C: \ Programme (x86) \ Microsoft Visual Studio 12.0 \ Common7 \ Tools \ Shortcuts. Versuchen Sie in Windows 8, nach "Visual Studio Tools" zu suchen.
goku_da_master
2
Für alle, die XSD suchen. Hier ist ein SO-Thread: stackoverflow.com/questions/22975031/…
SOReader
229

Sie haben zwei Möglichkeiten.

Methode 1. XSD- Tool


Angenommen, Sie haben Ihre XML-Datei an diesem Speicherort C:\path\to\xml\file.xml

  1. Öffnen Sie die Eingabeaufforderung für Entwickler.
    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 eingeben
  2. Ändern Sie den Speicherort in Ihr XML-Dateiverzeichnis, indem Sie Folgendes eingeben cd /D "C:\path\to\xml"
  3. Erstellen Sie eine XSD-Datei aus Ihrer XML-Datei, indem Sie Folgendes eingebenxsd file.xml
  4. Erstellen Sie C # -Klassen durch Eingabexsd /c file.xsd

Und das ist es! Sie haben C # -Klassen aus der XML-Datei in generiertC:\path\to\xml\file.cs

Methode 2 - Spezial einfügen


Erforderliches Visual Studio 2012+

  1. Kopieren Sie den Inhalt Ihrer XML-Datei in die Zwischenablage
  2. Fügen Sie Ihrer Lösung eine neue, leere Klassendatei hinzu ( Shift+ Alt+ C)
  3. Öffnen Sie diese Datei und klicken Sie im Menü auf Edit > Paste special > Paste XML As Classes
    Geben Sie hier die Bildbeschreibung ein

Und das ist es!

Verwendungszweck


Die Verwendung dieser Hilfsklasse ist sehr einfach:

using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;

namespace Helpers
{
    internal static class ParseHelpers
    {
        private static JavaScriptSerializer json;
        private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }

        public static Stream ToStream(this string @this)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(@this);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }


        public static T ParseXML<T>(this string @this) where T : class
        {
            var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
        }

        public static T ParseJSON<T>(this string @this) where T : class
        {
            return JSON.Deserialize<T>(@this.Trim());
        }
    }
}

Jetzt müssen Sie nur noch Folgendes tun:

    public class JSONRoot
    {
        public catalog catalog { get; set; }
    }
    // ...

    string xml = File.ReadAllText(@"D:\file.xml");
    var catalog1 = xml.ParseXML<catalog>();

    string json = File.ReadAllText(@"D:\file.json");
    var catalog2 = json.ParseJSON<JSONRoot>();
Damian Drygiel
quelle
16
+1 gute Antwort. Der Paste XML As ClassesBefehl zielt jedoch nur auf .NET 4.5 ab
Ravy Amiry
1
Dies ist eine großartige Möglichkeit, das Modell zu generieren, wenn Sie vs2012 + installiert haben. Ich habe anschließend die ReSharper-Codebereinigung ausgeführt, um automatische Eigenschaften zu verwenden, und dann auch andere Aufräumarbeiten durchgeführt. Sie können über diese Methode generieren und bei Bedarf in ein älteres Projekt kopieren.
Scotty.NET
4
Das Anvisieren von .net4.5 ist kein Problem. Starten Sie einfach ein temporäres Projekt mit dotnet4.5, kopieren Sie es dort und kopieren Sie die Quelle in Ihr eigentliches Projekt.
LosManos
2
Wo ist das Objekt oder die Klasse "Katalog"?
CB4
3
Damit "XML als Klassen einfügen" in diesem Menü in der VS 2017-Community angezeigt wird, muss "ASP.NET und Webentwicklung" installiert sein. Wenn dies fehlt, führen Sie das VS-Installationsprogramm erneut aus, um Ihre Installation zu ändern.
Slion
89

Das folgende Snippet sollte den Trick ausführen (und Sie können die meisten Serialisierungsattribute ignorieren):

public class Car
{
  public string StockNumber { get; set; }
  public string Make { get; set; }
  public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
  [XmlElement("Car")]
  public Car[] Cars { get; set; }
}

...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

quelle
14
Dies ist eigentlich die einzige Antwort. Die akzeptierte Antwort weist einige Mängel auf, die Anfänger verwirren können.
Flamefire
24

Sehen Sie, ob dies hilft:

[Serializable()]
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

.

[Serializable()]
public class Car
{
    [System.Xml.Serialization.XmlElement()]
    public string StockNumber{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Make{ get; set; }

    [System.Xml.Serialization.XmlElement()]
    public string Model{ get; set; }
}

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.

Joel Coehoorn
quelle
9

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:

<Root> <-- well, the root
  <Cars> <-- an element (not a root), it being an array
    <Car> <-- an element, it being an array item
    ...
    </Car>
  </Cars>
</Root>
Janbak
quelle
7

Versuchen Sie diesen Codeblock, wenn Ihre XML-Datei irgendwo auf der Festplatte generiert wurde und wenn Sie Folgendes verwendet haben List<T>:

//deserialization

XmlSerializer xmlser = new XmlSerializer(typeof(List<Item>));
StreamReader srdr = new StreamReader(@"C:\serialize.xml");
List<Item> p = (List<Item>)xmlser.Deserialize(srdr);
srdr.Close();`

Hinweis: C:\serialize.xmlist der Pfad meiner XML-Datei. Sie können es für Ihre Bedürfnisse ändern.

Blatt Nainwal
quelle
6

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:

[XmlRoot("Cars")]
public class XmlData
{
    [XmlElement("Car")]
    public List<Car> Cars{ get; set; }
}

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

Und dann können Sie einfach anrufen:

var ser = new XmlSerializer(typeof(XmlData));
XmlData data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));
Kim Homann
quelle
Vielen Dank! Ihre Antwort ist genau das, was ich brauchte, da ich keine Protokolldateien im Wert von Gigabyte ändern wollte.
Colin
Erwähnenswert ist zwar, dass die XmlSerializer-Lösung sehr elegant, aber zugegebenermaßen auch nicht sehr schnell ist und empfindlich auf unerwartete XML-Daten reagiert. Wenn für Ihr Problem keine vollständige Deserialisierung erforderlich ist, sollten Sie die pragmatischere und performantere XmlReader-Klasse verwenden und die <Car> -Elemente durchlaufen.
Kim Homann
5

Probieren Sie diese generische Klasse für XML-Serialisierung und -Deserialisierung aus.

public class SerializeConfig<T> where T : class
{
    public static void Serialize(string path, T type)
    {
        var serializer = new XmlSerializer(type.GetType());
        using (var writer = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(writer, type);
        }
    }

    public static T DeSerialize(string path)
    {
        T type;
        var serializer = new XmlSerializer(typeof(T));
        using (var reader = XmlReader.Create(path))
        {
            type = serializer.Deserialize(reader) as T;
        }
        return type;
    }
}
Hasan Javaid
quelle
4

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 pathzu 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:

using System.Xml.Serialization;  // Added

public class Car
{
    public string StockNumber { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

[XmlRootAttribute("Cars")]
public class CarCollection
{
    [XmlElement("Car")]
    public Car[] Cars { get; set; }
}

Der andere Code von @erymski ...

using (TextReader reader = new StreamReader(path))
{
  XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
  return (CarCollection) serializer.Deserialize(reader);
}

... geht in Ihr Hauptprogramm (Program.cs) static CarCollection XCar()wie folgt :

using System;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApp2
{
    class Program
    {

        public static void Main()
        {
            var c = new CarCollection();

            c = XCar();

            foreach (var k in c.Cars)
            {
                Console.WriteLine(k.Make + " " + k.Model + " " + k.StockNumber);
            }
            c = null;
            Console.ReadLine();

        }
        static CarCollection XCar()
        {
            using (TextReader reader = new StreamReader(@"C:\Users\SlowLearner\source\repos\ConsoleApp2\ConsoleApp2\Class1.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(CarCollection));
                return (CarCollection)serializer.Deserialize(reader);
            }
        }
    }
}

Ich hoffe es hilft :-)

Langsamer Lerner
quelle
1
Es hat bei mir funktioniert. Dies ist auch eine perfekt funktionierende Lösung für die angegebene XML-Eingabe (wie im Beispiel von OP). [XmlElement ("Car")] ist das richtige Attribut. In anderen Beispielen verwendeten sie XmlArray usw., die nicht benötigt werden, solange die Eigenschaft als public Car [] Cars {get; einstellen; } und es würde es richtig deserialisieren. Vielen Dank.
Diwakar Padmaraja
3

Wie wäre es mit einer generischen Klasse zum Deserialisieren eines XML-Dokuments?

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Generic class to load any xml into a class
// used like this ...
// YourClassTypeHere InfoList = LoadXMLFileIntoClass<YourClassTypeHere>(xmlFile);

using System.IO;
using System.Xml.Serialization;

public static T LoadXMLFileIntoClass<T>(string xmlFile)
{
    T returnThis;
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    if (!FileAndIO.FileExists(xmlFile))
    {
        Console.WriteLine("FileDoesNotExistError {0}", xmlFile);
    }
    returnThis = (T)serializer.Deserialize(new StreamReader(xmlFile));
    return (T)returnThis;
}

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.

David C Fuchs
quelle
1
Dadurch konnte ich den Geschäftslogikcode erheblich verkleinern und die Funktionalität in einer Hilfsklasse mit allen von mir generierten <T> -Klassen zentralisieren. Ich hatte das XML bereits in einer Zeichenfolge, konnte es also wie folgt zusammenfassen: `public static T LoadXMLFileIntoClass <T> (Zeichenfolge xmlData)` {`XmlSerializer serializer = new XmlSerializer (typeof (T)); `return (T) serializer.Deserialize (neuer StringReader (xmlData)); `} Danke!
pwrgreg007
3

Einzeiler:

var object = (Cars)new XmlSerializer(typeof(Cars)).Deserialize(new StringReader(xmlString));
Andre M.
quelle
2

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

<?xml version="1.0" ?> 
 <TRANSACTION_RESPONSE>
    <TRANSACTION>
        <TRANSACTION_ID>25429</TRANSACTION_ID> 
        <MERCHANT_ACC_NO>02700701354375000964</MERCHANT_ACC_NO> 
        <TXN_STATUS>F</TXN_STATUS> 
        <TXN_SIGNATURE>a16af68d4c3e2280e44bd7c2c23f2af6cb1f0e5a28c266ea741608e72b1a5e4224da5b975909cc43c53b6c0f7f1bbf0820269caa3e350dd1812484edc499b279</TXN_SIGNATURE> 
        <TXN_SIGNATURE2>B1684258EA112C8B5BA51F73CDA9864D1BB98E04F5A78B67A3E539BEF96CCF4D16CFF6B9E04818B50E855E0783BB075309D112CA596BDC49F9738C4BF3AA1FB4</TXN_SIGNATURE2> 
        <TRAN_DATE>29-09-2015 07:36:59</TRAN_DATE> 
        <MERCHANT_TRANID>150929093703RUDZMX4</MERCHANT_TRANID> 
        <RESPONSE_CODE>9967</RESPONSE_CODE> 
        <RESPONSE_DESC>Bank rejected transaction!</RESPONSE_DESC> 
        <CUSTOMER_ID>RUDZMX</CUSTOMER_ID> 
        <AUTH_ID /> 
        <AUTH_DATE /> 
        <CAPTURE_DATE /> 
        <SALES_DATE /> 
        <VOID_REV_DATE /> 
        <REFUND_DATE /> 
        <REFUND_AMOUNT>0.00</REFUND_AMOUNT> 
    </TRANSACTION>
  </TRANSACTION_RESPONSE> 

Das obige XML wird in zwei Ebenen behandelt

  [XmlType("TRANSACTION_RESPONSE")]
public class TransactionResponse
{
    [XmlElement("TRANSACTION")]
    public BankQueryResponse Response { get; set; }

}

Die innere Ebene

public class BankQueryResponse
{
    [XmlElement("TRANSACTION_ID")]
    public string TransactionId { get; set; }

    [XmlElement("MERCHANT_ACC_NO")]
    public string MerchantAccNo { get; set; }

    [XmlElement("TXN_SIGNATURE")]
    public string TxnSignature { get; set; }

    [XmlElement("TRAN_DATE")]
    public DateTime TranDate { get; set; }

    [XmlElement("TXN_STATUS")]
    public string TxnStatus { get; set; }


    [XmlElement("REFUND_DATE")]
    public DateTime RefundDate { get; set; }

    [XmlElement("RESPONSE_CODE")]
    public string ResponseCode { get; set; }


    [XmlElement("RESPONSE_DESC")]
    public string ResponseDesc { get; set; }

    [XmlAttribute("MERCHANT_TRANID")]
    public string MerchantTranId { get; set; }

}

Auf die gleiche Weise benötigen Sie mehrere Ebenen mit car as array Überprüfen Sie dieses Beispiel auf mehrstufige Deserialisierung

makdu
quelle
1

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:

using System.Xml;
using System.Xml.Schema;

[TestMethod]
public void GenerateXsdFromXmlTest()
{
    string folder = @"C:\mydir\mydata\xmlToCSharp";
    XmlReader reader = XmlReader.Create(folder + "\some_xml.xml");
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();

    schemaSet = schema.InferSchema(reader);


    foreach (XmlSchema s in schemaSet.Schemas())
    {
        XmlWriter xsdFile = new XmlTextWriter(folder + "\some_xsd.xsd", System.Text.Encoding.UTF8);
        s.Write(xsdFile);
        xsdFile.Close();
    }
}

// now from the visual studio command line type: xsd some_xsd.xsd /classes
goku_da_master
quelle
1

Sie können nur ein Attribut für Ihre Cars-Autoeigenschaft von XmlArrayItem in XmlElment ändern. Das heißt, von

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlArrayItem(typeof(Car))]
    public Car[] Car { get; set; }
}

zu

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlElement("Car")]
    public Car[] Car { get; set; }
}
XU Weijiang
quelle
1

Meine Lösung:

  1. Verwenden Sie Edit > Past Special > Paste XML As Classesdiese Option , um die Klasse in Ihren Code aufzunehmen
  2. Versuchen Sie Folgendes: Erstellen Sie eine Liste dieser Klasse ( List<class1>) und XmlSerializerserialisieren Sie diese Liste mit einer in eine xmlDatei.
  3. Jetzt ersetzen Sie einfach den Hauptteil dieser Datei durch Ihre Daten und versuchen deserializees.

Code:

StreamReader sr = new StreamReader(@"C:\Users\duongngh\Desktop\Newfolder\abc.txt");
XmlSerializer xml = new XmlSerializer(typeof(Class1[]));
var a = xml.Deserialize(sr);
sr.Close();

HINWEIS: Sie müssen auf den Stammnamen achten, ändern Sie ihn nicht. Meins ist "ArrayOfClass1"

haiduong87
quelle
1
async public static Task<JObject> XMLtoNETAsync(XmlDocument ToConvert)
{
    //Van XML naar JSON
    string jsonText = await Task.Run(() => JsonConvert.SerializeXmlNode(ToConvert));

    //Van JSON naar .net object
    var o = await Task.Run(() => JObject.Parse(jsonText));

    return o;
}
Zoidbergseasharp
quelle
1
Bitte setzen Sie Ihre Antwort immer in einen Kontext, anstatt nur Code einzufügen. Sehen Sie hier für weitere Details.
gehbiszumeis