How to Deserialize XML document
Asked Answered
B

16

537

How do I Deserialize this XML document:

<?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>

I have this:

[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;
    }
}

that don't seem to work :-(

Boots answered 12/12, 2008 at 21:49 Comment(3)
I think you need to escape the angle brackets in your sample doc.Gobo
This answer is really really good: https://mcmap.net/q/73593/-how-to-deserialize-xml-documentPlautus
reader.ReadToEnd(); is wrong!!!Habergeon
C
391

Here's a working version. I changed the XmlElementAttribute labels to XmlElement because in the xml the StockNumber, Make and Model values are elements, not attributes. Also I removed the reader.ReadToEnd(); (that function reads the whole stream and returns a string, so the Deserialize() function couldn't use the reader anymore...the position was at the end of the stream). I also took a few liberties with the naming :).

Here are the classes:

[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; }
}

The Deserialize function:

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

And the slightly tweaked xml (I needed to add a new element to wrap <Cars>...Net is picky about deserializing 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>
Cronk answered 12/12, 2008 at 22:40 Comment(5)
The [Serializable] is redundant if using XmlSerializer; XmlSerializer simply never checks for that. Likewise, most of the [Xml...] attributes are redundant, as it simply mimics the default behaviour; i.e. by default a property called StockNumber is stored as an element named <StockNumber> - no need for attributes for that.Slenderize
Note that XmlElementAttribute = XmlElement (it is a language feature that you can omit the suffix "Attribute") Real solution here is the removing of the ReadToEnd() call and adding of a root node. But better use the code from erymski which solves the question (parse the given xml)Mackler
Thanks Kevin, But what if I removed the CarsCollection from sample XML. I removed Carscollection from classes and Deserealize code , but didn't succeed.Elbertine
As I understand it, Serializable is depricated and shouldn't be used anymore.Giltedged
@Mackler +1 for removing ReadToEnd, -1 for tweaking the XML, when it is not necessary.Trichloromethane
S
509

How about you just save the xml to a file, and use xsd to generate C# classes?

  1. Write the file to disk (I named it foo.xml)
  2. Generate the xsd: xsd foo.xml
  3. Generate the C#: xsd foo.xsd /classes

Et voila - and C# code file that should be able to read the data via XmlSerializer:

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

(include the generated foo.cs in the project)

Slenderize answered 12/12, 2008 at 22:44 Comment(7)
YOU... are the man! Thanks. for anyone that needs it, "path" can be a Stream that you create from a web response like so: var resp = response.Content.ReadAsByteArrayAsync(); var stream = new MemoryStream(resp.Result);Emboly
Awesome idea, but couldn't get it to work right for my slightly more complicated model with batches of nested arrays. I kept getting type conversion errors for the nested arrays -- plus the naming scheme generated left something to be desired. Therefore I ended up going the custom route.Ilion
How to get to xsd.exeAgriculturist
xsd.exe is available from the visual studio command prompt, not windows command prompt. See if you can open the command prompt from within visual studio under Tools. If not, try accessing it from the visual studio folder. For VS 2012 it was located here: C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts. In Windows 8 try searching for "Visual Studio Tools".Unni
For everybody who's looking for XSD. Here's a SO thread: #22975531Bacterin
If I am not saving xml into file and reading from ServiceModel.Channels.Message GetReaderAtBodyContents which will give xmlReader then how to use xmlserializer ?Mono
Update to goku_da_master: In VS2022: Place the .xlm-file in your solution. Open the Developer Powershell (View in the Menu > Terminal. Or use the schortcut Ctrl + ù.) Execute the commands as described under point 2 and three in the answer provided by Mr. Gravell here above.Limonite
C
391

Here's a working version. I changed the XmlElementAttribute labels to XmlElement because in the xml the StockNumber, Make and Model values are elements, not attributes. Also I removed the reader.ReadToEnd(); (that function reads the whole stream and returns a string, so the Deserialize() function couldn't use the reader anymore...the position was at the end of the stream). I also took a few liberties with the naming :).

Here are the classes:

[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; }
}

The Deserialize function:

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

And the slightly tweaked xml (I needed to add a new element to wrap <Cars>...Net is picky about deserializing 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>
Cronk answered 12/12, 2008 at 22:40 Comment(5)
The [Serializable] is redundant if using XmlSerializer; XmlSerializer simply never checks for that. Likewise, most of the [Xml...] attributes are redundant, as it simply mimics the default behaviour; i.e. by default a property called StockNumber is stored as an element named <StockNumber> - no need for attributes for that.Slenderize
Note that XmlElementAttribute = XmlElement (it is a language feature that you can omit the suffix "Attribute") Real solution here is the removing of the ReadToEnd() call and adding of a root node. But better use the code from erymski which solves the question (parse the given xml)Mackler
Thanks Kevin, But what if I removed the CarsCollection from sample XML. I removed Carscollection from classes and Deserealize code , but didn't succeed.Elbertine
As I understand it, Serializable is depricated and shouldn't be used anymore.Giltedged
@Mackler +1 for removing ReadToEnd, -1 for tweaking the XML, when it is not necessary.Trichloromethane
D
267

You have two possibilities.

Method 1. XSD tool


Suppose that you have your XML file in this location C:\path\to\xml\file.xml
  1. Open Developer Command Prompt
    You can find it in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Or if you have Windows 8 can just start typing Developer Command Prompt in Start screen
  2. Change location to your XML file directory by typing cd /D "C:\path\to\xml"
  3. Create XSD file from your xml file by typing xsd file.xml
  4. Create C# classes by typing xsd /c file.xsd

And that's it! You have generated C# classes from xml file in C:\path\to\xml\file.cs

Method 2 - Paste special


Required Visual Studio 2012+
  1. Copy content of your XML file to clipboard
  2. Add to your solution new, empty class file (Shift+Alt+C)
  3. Open that file and in menu click Edit > Paste special > Paste XML As Classes
    enter image description here

And that's it!

Usage


Usage is very simple with this helper class:

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

All you have to do now, is:

    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>();
Delogu answered 27/10, 2013 at 2:11 Comment(11)
+1 good answer. But, the Paste XML As Classes command targets only .NET 4.5Frigidaire
This is a great way to generate the model if you do have vs2012+ installed. I did run ReSharper code cleanup afterwards to use automatic properties and then did some other tidying up as well. You could generate via this method and then copy into an older proj if need be.Ornery
Targetting .net4.5 is not a problem. Just fire up a temporary project with dotnet4.5, do your copy-paste there and copy source to your actual project.Zeeba
where is the "catalog" object or class?Missend
'catalog' would be top (header) class from file generated in 'Paste Special'.Cummine
For "Paste XML as classes" to show up in that menu on VS 2017 Community you need to have installed "ASP.NET and web development". If missing just run VS installer again to modify your installation.Dalmatian
This has nothing to do with the question, and non of our customers have visual studio or its tools installed..Efrainefram
that helper class is great, but for those not using VS on Windows, go here to turn your XML into classes first: xmltocsharp.azurewebsites.netTridactyl
@Damian that is a nice walk-through on PasteSpecial. IMO you do not need to clutter your answer with unneeded helper methods. OP didn't ask about JSON. Also, reading all text into a string is not needed or ideal for large inputs. If you do have a string already, use StringReader to convert.Trichloromethane
I keep coming back to this answer... and just end up using paste special again and againScapegrace
Paste XML as Classes does not produce a desired result (VS 2022 Community)., third party online tools gives a much cleaner code, eg: json2csharp.com, you have an an option to convert from XML tol C# ClassPolicyholder
V
110

The following snippet should do the trick (and you can ignore most of the serialization attributes):

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);
}
Valente answered 22/12, 2008 at 22:24 Comment(3)
This is actually the one and only answer. The accepted answer has a couple of flaws that can confuse beginners.Mackler
@AndrewDennison you are talking to nobodyCornet
This should be the accepted answer. I was in same situation as the OP but had no control over the XML whatsoever so wrapping the root element inside a new root element was not option. Using XmlElement directly on the array instead of mixing various combination of XmlArray and XmlArrayItem worked just fine.Orme
S
25

See if this helps:

[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; }
}

And failing that use the xsd.exe program that comes with visual studio to create a schema document based on that xml file, and then use it again to create a class based on the schema document.

Seiter answered 12/12, 2008 at 22:9 Comment(0)
C
11

I don't think .net is 'picky about deserializing arrays'. The first xml document is not well formed. There is no root element, although it looks like there is. The canonical xml document has a root and at least 1 element (if at all). In your example:

<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>
Chromatogram answered 26/1, 2012 at 12:6 Comment(0)
O
11

For Beginners

I found the answers here to be very helpful, that said I still struggled (just a bit) to get this working. So, in case it helps someone I'll spell out the working solution:

XML from Original Question. The xml is in a file Class1.xml, a path to this file is used in the code to locate this xml file.

I used the answer by @erymski to get this working, so created a file called Car.cs and added the following:

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

The other bit of code provided by @erymski ...

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

... goes into your main program (Program.cs), in static CarCollection XCar() like this:

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

Hope it helps :-)

Ottoman answered 22/5, 2018 at 9:36 Comment(1)
It worked for me. This is a perfectly working solution for the given xml input (as in OP's example) too. [XmlElement("Car")] is the right attribute. In other examples they used XmlArray etc which are not needed as long as we have the property defined as public Car[] Cars { get; set; } and it would deserialize it correctly. Thanks.Gwen
W
9

try this block of code if your .xml file has been generated somewhere in disk and if you have used 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();`

Note: C:\serialize.xml is my .xml file's path. You can change it for your needs.

Wagers answered 7/10, 2013 at 11:6 Comment(0)
T
9

Kevin's anser is good, aside from the fact, that in the real world, you are often not able to alter the original XML to suit your needs.

There's a simple solution for the original XML, too:

[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; }
}

And then you can simply call:

var ser = new XmlSerializer(typeof(XmlData));
var data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));
Thorstein answered 13/1, 2018 at 14:11 Comment(2)
Thanks! Your answer is exactly what I needed, as I did not want to alter gigabytes worth of log files.Sesterce
Although it's worth mentioning that the XmlSerializer solution is very elegant but admittedly also not very fast and reacts sensitively to unexpected Xml data. So if your problem doesn't require a complete deserialization, you should consider using the more pragmatic and performant XmlReader class only and loop through the <Car> elements.Thorstein
O
7

One liner:

var object = (Cars)new XmlSerializer(typeof(Cars)).Deserialize(new StringReader(xmlString));
Oswin answered 20/9, 2019 at 12:36 Comment(0)
P
6

Try this Generic Class For Xml Serialization & Deserialization.

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;
    }
}
Percussive answered 12/5, 2016 at 6:18 Comment(0)
C
5

How about a generic class to deserialize an XML document

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 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;
}

This part may, or may not be necessary. Open the XML document in Visual Studio, right click on the XML, choose properties. Then choose your schema file.

Crepuscule answered 2/12, 2017 at 5:0 Comment(1)
This allowed me to shrink the business logic code quite a bit and centralize the functionality in a helper class with all the <T> classes I generated. I already had the XML in a string, so could condense it to this: ` public static T LoadXMLFileIntoClass<T>(string xmlData) ` { ` XmlSerializer serializer = new XmlSerializer(typeof(T)); ` return (T)serializer.Deserialize(new StringReader(xmlData)); ` } Thanks!Impossible
M
3

The idea is to have all level being handled for deserialization Please see a sample solution that solved my similar issue

<?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> 

The above XML is handled in two level

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

}

The Inner level

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

}

Same Way you need multiple level with car as array Check this example for multilevel deserialization

Multiflorous answered 30/9, 2015 at 3:11 Comment(0)
U
1

If you're getting errors using xsd.exe to create your xsd file, then use the XmlSchemaInference class as mentioned on msdn. Here's a unit test to demonstrate:

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
Unni answered 16/10, 2014 at 20:39 Comment(0)
M
1

You can just change one attribute for you Cars car property from XmlArrayItem to XmlElment. That is, from

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

to

[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
    [XmlElement("Car")]
    public Car[] Car { get; set; }
}
Meaganmeager answered 17/11, 2014 at 5:20 Comment(0)
R
1

My solution:

  1. Use Edit > Past Special > Paste XML As Classes to get the class in your code
  2. Try something like this: create a list of that class (List<class1>), then use the XmlSerializer to serialize that list to a xml file.
  3. Now you just replace the body of that file with your data and try to deserialize it.

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

NOTE: you must pay attention to the root name, don't change it. Mine is "ArrayOfClass1"

Remedial answered 9/8, 2017 at 11:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.