Deserialize from WebServices C# - c#

Here's my issue : I need to get a list of resources from a web services, and deserialize it into object. But it doesn't work, despite the facts my code worked with another xml file. So I can't figure why it doesn't work, and I'm stuck with that !
Here's the XML :
<ResourceDataSet xmlns="http://schemas.microsoft.com/office/project/server/webservices/ResourceDataSet/">
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
<Resources>
<RES_UID>blabla</RES_UID>
<RES_NAME>blabla</RES_NAME>
<RES_CODE>blabla</RES_CODE>
<RES_GROUP>blabla</RES_GROUP>
<RES_COST_CENTER>blabla</RES_COST_CENTER>
</Resources>
</ResourceDataSet>
The class I want to deserialize into :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Threading.Tasks;
using System.Collections;
namespace TestWPF
{
[Serializable()]
public class Employee
{
[System.Xml.Serialization.XmlElement("RES_UID")]
public int RES_UID { get; set; }
[System.Xml.Serialization.XmlElement("RES_NAME")]
public String RES_NAME { get; set; }
[System.Xml.Serialization.XmlElement("RES_CODE")]
public String RES_CODE { get; set; }
[System.Xml.Serialization.XmlElement("RES_GROUP")]
public String RES_GROUP { get; set; }
[System.Xml.Serialization.XmlElement("RES_COST_CENTER")]
public String RES_COST_CENTER { get; set; }
public Employee()
{ }
public Employee(int r_id, String res_name, String res_code, String res_group, String res_cost_center)
{
this.RES_UID = r_id;
this.RES_NAME = res_name;
this.RES_CODE = res_code;
this.RES_GROUP = res_group;
this.RES_COST_CENTER = res_cost_center;
}
}
[Serializable()]
[System.Xml.Serialization.XmlRoot("ResourceDataSet")]
public class EmployeeList //: IEnumerator, IEnumerable
{
public EmployeeList() {Items = new List<Employee>();}
[XmlArray("ResourceDataSet")]
[XmlArrayItem("Resources")]
public List<Employee> Items {get;set;}
}
}
And the code I use to deserialize :
EmployeeList lstEmployee = null;
XmlSerializer xs = new XmlSerializer(typeof(ServersList));
StreamReader sr = new StreamReader("testEmployee.xml");
lstEmployee = (EmployeeList)serializer.Deserialize(sr);
reader.Close();
for (int i = 0; i < lstEmployee.Items.Count(); i++)
{
MessageBox.Show(lstEmployee.Items[i].RES_NAME);
}
And when I try to launch I receive this error message :

Firstly your xml file is invalid - RES_UID is expecting an int, so even when you get your serialization working you'll run into that problem.
You're also not taking into account the namespace. The following class works:
[Serializable()]
public class Employee
{
[System.Xml.Serialization.XmlElement("RES_UID")]
public int RES_UID { get; set; }
[System.Xml.Serialization.XmlElement("RES_NAME")]
public String RES_NAME { get; set; }
[System.Xml.Serialization.XmlElement("RES_CODE")]
public String RES_CODE { get; set; }
[System.Xml.Serialization.XmlElement("RES_GROUP")]
public String RES_GROUP { get; set; }
[System.Xml.Serialization.XmlElement("RES_COST_CENTER")]
public String RES_COST_CENTER { get; set; }
public Employee()
{ }
public Employee(int r_id, String res_name, String res_code, String res_group, String res_cost_center)
{
this.RES_UID = r_id;
this.RES_NAME = res_name;
this.RES_CODE = res_code;
this.RES_GROUP = res_group;
this.RES_COST_CENTER = res_cost_center;
}
}
[Serializable()]
[System.Xml.Serialization.XmlRoot("ResourceDataSet", Namespace = "http://schemas.microsoft.com/office/project/server/webservices/ResourceDataSet/")]
public class EmployeeList //: IEnumerator, IEnumerable
{
public EmployeeList() {Items = new List<Employee>();}
[XmlElement("Resources", Type = typeof(Employee))]
public List<Employee> Items {get;set;}
}
}
and your calling code with the typos fixed:
EmployeeList lstEmployee = null;
XmlSerializer xs = new XmlSerializer(typeof(EmployeeList));
StreamReader sr = new StreamReader("testEmployee.xml");
lstEmployee = (EmployeeList)xs.Deserialize(sr);
sr.Close();
for (int i = 0; i < lstEmployee.Items.Count(); i++)
{
MessageBox.Show(lstEmployee.Items[i].RES_NAME);
}
Remember to fix your xml to be ints otherwise it still won't work

You need to either decorate your root entity with the XmlRoot attribute or Or specify the root attribute when de serializing at runtime.
Here is a thread about this issue
https://stackoverflow.com/a/1557145/1305119

Related

How to deserialize a string from an XML content?

I have an XML like this:
<XmlSports CreateDate="2022-12-04T17:47:53.5569879Z">
<Sport Name="eSports" ID="2357">
<Event Name="NBA2K, NBA Blitz League" ID="66838" IsLive="false" CategoryID="9357">
<Match Name="LA Clippers (THA KID) Esports - Milwaukee Bucks (SHARPSHOOTER)" ID="2711992" StartDate="2022-12-04T17:36:00" MatchType="Live">
<Bet Name="Money Line" ID="43859970" IsLive="true">
<Odd Name="1" ID="297613016" Value="2.26"/>
<Odd Name="2" ID="297613021" Value="1.58"/>
</Bet>
<Bet Name="Spread" ID="43859969" IsLive="true">
<Odd Name="1" ID="297614398" Value="1.83" SpecialBetValue="2.5"/>
<Odd Name="2" ID="297614399" Value="1.90" SpecialBetValue="2.5"/>
</Bet>
<Bet Name="Total" ID="43859971" IsLive="true">
<Odd Name="Over" ID="297613741" Value="1.86" SpecialBetValue="140.5"/>
<Odd Name="Under" ID="297613740" Value="1.86" SpecialBetValue="140.5"/>
</Bet>
</Match>
</Event>
<Event Name="FIFA, GT League" ID="62647" IsLive="false" CategoryID="8212">
.
. **and so on, the content is too long to post it here**
.
</Sport>
</XmlSports>
and the goal is to deserialize it into C# classes.
My classes are as such:
using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
[Serializable, XmlRoot("Sport")]
public class Sport
{
[XmlElement("ID")]
public int ID { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("Event")]
public List<Event> Events { get; set; }
}
}
also:
using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
[XmlType("Event")]
public class Event
{
[XmlElement("ID")]
public int ID { get; set; }
[XmlElement("Name")]
public string Name { get; set; }
[XmlElement("CategoryID")]
public int CategoryID { get; set; }
[XmlElement("IsLive")]
public bool IsLive { get; set; }
[XmlElement("Match")]
public List<Match> Matches { get; set; }
}
}
I also have the classes: Odd, Match and Bet
This is my code:
private static async Task<Sport> DeserializeXMLToObject()
{
private static readonly string xmlUrl = #"*here is the url*";
XmlSerializer ser = new XmlSerializer(typeof(Sport));
//WebClient client = new WebClient();
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(xmlUrl).Result;
string xml = "";
if (response.IsSuccessStatusCode)
{
xml = response.Content.ReadAsStringAsync().Result;
}
Sport sport = new Sport();
using(TextReader reader = new StringReader(xml))
{
sport = (Sport)ser.Deserialize(reader);
}
return sport;
}
but on this line
sport = (Sport)ser.Deserialize(reader);
it gives me the following error:
InnerException = {"<XmlSports xmlns=''> was not expected."}
I think it is because I've had created a class XmlSports but I removed it because when I run code first migration with Entity Framework, it said that there was an error because it couldn't create a primary key for the table XmlSports, so I removed this class and made the Sport class the root class instead.
I tried to create an xsd file from this xml (I created a test.xml file and copied and pasted the content from the url) but it didn't happen because it said that: There was an error processing 'test.xml'.
I don't have experience with xml content and serialization and deserialization in general so it's pretty hard for me to understand what's wrong and how to fix it.
Any suggestions would be highly appreciated!
Thank you!
This should get you started. If you need more help ask
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(XmlSports));
XmlSports sports = (XmlSports)serializer.Deserialize(reader);
}
}
public class XmlSports
{
public Sport Sport { get; set; }
}
public class Sport
{
[XmlAttribute("ID")]
public int ID { get; set; }
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlElement("Event")]
public List<Event> Events { get; set; }
}
public class Event
{
[XmlAttribute("ID")]
public int ID { get; set; }
[XmlAttribute("Name")]
public string Name { get; set; }
[XmlAttribute("CategoryID")]
public int CategoryID { get; set; }
[XmlAttribute("IsLive")]
public bool IsLive { get; set; }
[XmlElement("Match")]
public List<Match> Matches { get; set; }
}
public class Match
{ }
}

Traversing an XML file using Linq to XML not working as expected

Sorry for the somewhat basic question, but what can I say. I can't figure it out. The problem is that there's a foreach loop that's supposed to iterate through the rows (sections) and while it works for the first section, the second time through the loop it doesn't seem to read the second section. The same data is stored in version. BTW, the way the method is called I would be passing in ProductName as a parameter (There will be multiple products represented here and also a version number (e.g. v2.0.0) that I'll need to filter the results for too.
So I have an XML file that looks like this:
<Products>
<ProductName1>
<v2.0.0>
<GUID>"{B5ECEC43-5406-4E4D-96D9-456823100313}"</GUID>
<VersionNameToUninstall>"2.0.0 - 2.0.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.0-Uninst.iss"</UninstallResponseFile>
</v2.0.0>
<v2.0.3>
<GUID>"{1D6C02D7-8E87-43BE-8AB2-1FF0E5ACD410}"</GUID>
<VersionNameToUninstall>"2.0.3"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.3-Uninst.iss"</UninstallResponseFile>
</v2.0.3>
</ProductName1>
<ProductName2>
<v3.0.0>
<GUID>"{ABCDEC43-5406-4E4D-96D9-456823101234}"</GUID>
<VersionNameToUninstall>"2.2.0 - 2.2.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.2.0-Uninst.iss"</UninstallResponseFile>
</v3.0.0>
<v4.0.0>
<GUID>"{5D6C02D7-8E87-43BE-8AB2-1FF0E5ACD589}"</GUID>
<VersionNameToUninstall>"4.0.0"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-4.0.0-Uninst.iss"</UninstallResponseFile>
</v4.0.0>
</ProductName2>
</Products>
There will only be 10 or so versions (e.g. v2.x.x) so there's not a lot of data here. So I created a multidimensional (nested) class/struct to hold the data and when I try my code to read the data it's not working.
Here are the classes/stucts (I've tried both and neither works) that I'm trying to populate:
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row {get;set;}
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
So here's my code. Please just ignore the Stream - that's so I can embed this XML file in the .exe and not have it be a separate file:
public static List<TopLevelObject> GetGUIDSFromFile(string GUIDKey)
List<InstallScriptMSIXMLTopLevelObject> installScriptMSIXMLTopLevelObjectList = new List<InstallScriptMSIXMLTopLevelObject>();
Stream GUIDXmlFileStream = typeof(PGCommonCA).Assembly.GetManifestResourceStream("PGCommonCA.ProductGUIDs.xml");
XElement xElement = XElement.Load(GUIDXmlFileStream);
var versions = xElement.Elements(GUIDKey).Descendants();
foreach (var version in versions)
{
TopLevelObject topLevelObject = new TopLevelObject();
RowLevelObject rowLevelObject = new RowLevelObject();
TopLevelObject.Version = version.Name.LocalName;
RowLevelObject.Guid = version.Element("GUID").Value;
RowLevelObject.VersionName = version.Element("VersionNameToUninstall").Value;
RowLevelObject.UninstallFileName = version.Element("UninstallResponseFile").Value;
TopLevelObjectList.Add(topLevelObject);
}
return TopLevelObjectList;
}
I know there are many ways to read XML and my choice doesn't work so I'm looking for another simple solution.
The following works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}
I figured it out (many thanks to jdweng!!). Here's the final solution based on the revised XML at the top:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static TopLevelObject GetInfo(string xmlKey)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Descendants(xmlKey).Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}

Parse complex xml to fetch particular node text in c#

Parsing XML file using SSIS / C#
operations like fetching record count from trailer , TIN from body and store into a variable or somewhere temporarily(your suggestions please) for further processing. I don't want to store it in a table.
Please find the sample xml mentioned below
<ACOParticipantData xmlns:xsi="">
<Header>
<HeaderCode>HDR_PFPRVDR</HeaderCode>
<FileCreationDate>20160101</FileCreationDate>
<ACOProgCode>21</ACOProgCode>
</Header>
<Participants>
<Participant>
<ACO_ID>V199</ACO_ID>
<TIN>123456789</TIN>
<Old_TIN>987654321</Old_TIN>
<Org_NPI>1234567890</Org_NPI>
<Ind_NPI>1234567890</Ind_NPI>
<CCN>123456</CCN>
<PRG_Eff_Dt>20160101</PRG_Eff_Dt>
<PRG_Term_Dt>20161231</PRG_Term_Dt>
</Participant>
</Participants>
<Trailer>
<TrailerCode>TRL_PFPRVDR</TrailerCode>
<FileCreationDate>20160101</FileCreationDate>
<RecordCount>1</RecordCount>
</Trailer>
</ACOParticipantData>
You need to get fist get list of Participants then fetch all Participants tin number into list like
Here i created console app for your demonstration purpose.
class Program
{
static void Main(string[] args)
{
XDocument doc = XDocument.Load(#"Path to your xml file");
List<long> tinList = new List<long>();
tinList = doc.Descendants("Participants").Elements().Elements("TIN").Select(x => (long)x).ToList();
foreach (long tin in tinList)
{
Console.WriteLine(tin);
}
Console.ReadLine();
}
}
Output: (For 2 Participants)
You need to create a class for each node and use XML deserialisation to create the object.
I had to remove the empty namespace as the deserialisation process requires a valid namespace.
Also you can change the type of the properties according to your needs.
using System;
using System.IO;
using System.Xml.Serialization;
using System.Linq;
public class Program
{
public class ACOParticipantData
{
public Header Header { get; set; }
public Participant[] Participants { get; set; }
}
public class Header
{
public string HeaderCode { get; set; }
public string FileCreationDate { get; set; }
public string ACOProgCode { get; set; }
}
public class Participant
{
public string ACO_ID { get; set; }
public string TIN { get; set; }
public string Old_TIN { get; set; }
public string Org_NPI { get; set; }
public string Ind_NPI { get; set; }
public string CCN { get; set; }
public string PRG_Eff_Dt { get; set; }
public string PRG_Term_Dt { get; set; }
}
public class Trailer
{
public string TrailerCode { get; set; }
public string FileCreationDate { get; set; }
public string RecordCount { get; set; }
}
public static void Main()
{
var xmlString = #"<ACOParticipantData>
<Header>
<HeaderCode>HDR_PFPRVDR</HeaderCode>
<FileCreationDate>20160101</FileCreationDate>
<ACOProgCode>21</ACOProgCode>
</Header>
<Participants>
<Participant>
<ACO_ID>V199</ACO_ID>
<TIN>123456789</TIN>
<Old_TIN>987654321</Old_TIN>
<Org_NPI>1234567890</Org_NPI>
<Ind_NPI>1234567890</Ind_NPI>
<CCN>123456</CCN>
<PRG_Eff_Dt>20160101</PRG_Eff_Dt>
<PRG_Term_Dt>20161231</PRG_Term_Dt>
</Participant>
<Participant>
<ACO_ID>V199</ACO_ID>
<TIN>123456780</TIN>
<Old_TIN>987654321</Old_TIN>
<Org_NPI>1234567890</Org_NPI>
<Ind_NPI>1234567890</Ind_NPI>
<CCN>123456</CCN>
<PRG_Eff_Dt>20160101</PRG_Eff_Dt>
<PRG_Term_Dt>20161231</PRG_Term_Dt>
</Participant>
</Participants>
<Trailer>
<TrailerCode>TRL_PFPRVDR</TrailerCode>
<FileCreationDate>20160101</FileCreationDate>
<RecordCount>1</RecordCount>
</Trailer>
</ACOParticipantData>";
var serializer = new XmlSerializer(typeof(ACOParticipantData));
ACOParticipantData obj = null;
using (var reader = new StringReader(xmlString))
{
obj = (ACOParticipantData)serializer.Deserialize(reader);
}
if (obj == null)
{
return;
}
foreach (var tin in obj.Participants.Select(x => x.TIN))
{
Console.WriteLine(tin);
}
}
}
Output:
123456789
123456780

Null value on xml deserialization using [XmlAttribute]

I have the following XML;
<?xml version="1.0" encoding="UTF-8" ?>
<feedback>
<report_metadata>
<org_name>example.com</org_name>
</report_metadata>
</feedback>
and the following Feedback.cs class;
[XmlRoot("feedback", Namespace = "", IsNullable = false)]
public class Feedback
{
[XmlElement("report_metadata")]
public MetaData MetaData { get; set; }
}
[XmlType("report_metadata")]
public class MetaData
{
[XmlAttribute("org_name")]
public string Organisation { get; set; }
}
When I attempt to deserialize, the value for Organisation is null.
var xml = System.IO.File.ReadAllText("example.xml");
var serializer = new XmlSerializer(typeof(Feedback));
using (var reader = new StringReader(input))
{
var feedback = (Feedback)serializer.Deserialize(reader);
}
Yet, when I change Feedback.cs to the following, it works (obviously the property name has changed).
[XmlType("report_metadata")]
public class MetaData
{
//[XmlAttribute("org_name")]
public string org_name { get; set; }
}
I want the property to be Organisation, not org_name.
In the example XML file org_name is an XML element, not an XML attribute. Changing
[XmlAttribute("org_name")] to [XmlElement("org_name")] at the Organisation property will deserialize it as an element:
[XmlElement("org_name")]
public string Organisation { get; set; }
probably just typo
[XmlAttribute("org_name")]
public string Organisation { get; set; }
was supposed to be
[XmlElement("org_name")]
public string Organisation { get; set; }
Try to modify your Xml classes like
[XmlRoot(ElementName = "report_metadata")]
public class MetaData
{
[XmlElement(ElementName = "org_name")]
public string Organisation { get; set; }
}
[XmlRoot(ElementName = "feedback")]
public class Feedback
{
[XmlElement(ElementName = "report_metadata")]
public MetaData MetaData { get; set; }
}
Then you will get your desired output like
class Program
{
static void Main(string[] args)
{
Feedback feedback = new Feedback();
var xml = System.IO.File.ReadAllText(#"C:\Users\Nullplex6\source\repos\ConsoleApp4\ConsoleApp4\Files\XMLFile1.xml");
var serializer = new XmlSerializer(typeof(Feedback));
using (var reader = new StringReader(xml))
{
feedback = (Feedback)serializer.Deserialize(reader);
}
Console.WriteLine($"Organization: {feedback.MetaData.Organisation}");
Console.ReadLine();
}
}
Output:

Cannot parse simple XML into an object?

XML
<MeterWalkOrder>
<Name>Red Route</Name>
<Meters>
<Meter>
<MeterID>1</MeterID>
<SerialNumber>12345</SerialNumber>
</Meter>
<Meter>
<MeterID>2</MeterID>
<SerialNumber>SE</SerialNumber>
</Meter>
</Meters>
</MeterWalkOrder>
I cannot get simple XML into an object using any serializer
var xml = File.ReadAllText("WalkOrder.xml");
var xmlSerializer = new NFormats.Xml.XmlSerializer();
var obj = xmlSerializer.Deserialize<MeterWalkOrder>(new StringReader(xml));
I just get back 2 meter objects that have none of the attributes set and the name is not even set in walk order.
public partial class MeterWalkOrder
{
public MeterWalkOrder()
{
Meters = new List<Meter>();
}
[DataMember]
public String Name { get; set; }
}
}
using System;
using System.Xml.Serialization;
namespace WindowsFormsApplication1.Classes
{
public class Meter : IMeter
{
[XmlAttribute]
public int MeterID { get; set; }
[XmlAttribute]
public String SerialNumber { get; set; }
}
}
I am willing to try any xml serializer.
First of all i suggest you to read Introducing XML Serialization on MSDN
You made a couple of errors which lead to not mentioned exceptions thrown when you run your code.
in your Xml MeterID and SerialNumber are not attributes they are elements. (As Wyat Earp commented)
if you want to serialize something you have to tell that it should be [Serializable]
serialization requires an implemented public empty constructor
dont open streams when you are not closing them (use "using")
To test if your serialization works best first serialize, then check the output and then implement deserialize
Find a fully working example below:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace X123
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
MeterWalkOrder mo = new MeterWalkOrder();
mo.Name = "name";
mo.Meters.Add(new Meter { MeterID = 1, SerialNumber = "kdkdkd" });
mo.Meters.Add(new Meter { MeterID = 2, SerialNumber = "holladrio" });
var xmlSerializer = new XmlSerializer(typeof(MeterWalkOrder), new Type[] { typeof(Meter) });
{
xmlSerializer.Serialize(File.CreateText("hello.xml"), mo);
using (Stream s = File.OpenRead("hello.xml"))
{
var obj = xmlSerializer.Deserialize(s);
}
}
}
}
[Serializable]
public class MeterWalkOrder
{
public MeterWalkOrder()
{
}
public string Name { get; set; }
public List<Meter> Meters { get { return meters; } set { meters = value; } }
private List<Meter> meters = new List<Meter>();
}
[Serializable]
public class Meter
{
public Meter()
{
}
[XmlAttribute]
public int MeterID { get; set; }
[XmlAttribute]
public string SerialNumber { get; set; }
}
I used your sample XML and generated the classes inside VisualStudio with the Paste Special -> Paste XML as Classes, modified them a little bit to make them more readable and got the following class definitions from it:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class MeterWalkOrder
{
public string Name { get; set; }
[System.Xml.Serialization.XmlArrayItemAttribute("Meter", IsNullable = false)]
public List<MeterWalkOrderMeter> Meters { get; set; }
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class MeterWalkOrderMeter
{
public int MeterID { get; set; }
public string SerialNumber { get; set; }
}
using the above classes and the below code, it generated the objects without errors.
string inputXml = File.ReadAllText(#"C:\Temp\SOTest.xml");
//using System.Xml.Serialization;
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(MeterWalkOrder));
MeterWalkOrder outputObject = xmlSerializer.Deserialize(new StringReader(inputXml)) as MeterWalkOrder;

Categories

Resources