Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert from dynamic xml to c# object

I need inputs in converting an dynamic xml to defined c# object model

My sample xml is as below :

<?xml version="1.0" encoding="utf-8" ?>
  <Persons>
    <Person>
      <Id>10</Id>
      <FirstName> Dino </FirstName>
      <LastName> Esposito </LastName>
      <Addresses>
        <Address>
          <AddressType>BillTo</AddressType>
          <Street1></Street1>
          <Street2></Street2>
          <Street3></Street3>
          <City>Moscow</City>
        </Address>
        <Address>
          <AddressType>ShipTo</AddressType>
          <Street1></Street1>
          <Street2></Street2>
          <Street3></Street3>
          <City>Moscow</City>
        </Address>
        <Address>
          <AddressType>Contact</AddressType>
          <Street1></Street1>
          <Street2></Street2>
          <Street3></Street3>
          <City>Moscow</City>
        </Address>
      </Addresses>
    </Person>
  </Persons>

I am expecting the values of this xml to be converted to C# object at run time. I would want an object similar to the following to be defined: My Expected class object C# is as below:

public class Person
{
    public int Id { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public IList<Address> Addresses { get; set; }
}

public class Address
{
    public string AddressType { get; set; }
    public string Street1 { get; set; }
    public string Street2 { get; set; }
    public string Street3 { get; set; }
    public string City { get; set; }
}

I went through dynamic and ExpandoObject in C# 4.0, this approach is allowing me to get values dynamically by using keys. I dont know how i can populate these to my datamodel.

Note: I dont want to define this class model structure, this keeps changing over period of time. I am looking for a solution which allows me to get values like DynamicObject.Addresses.Address[0].City.

Kindly give your inputs.

like image 408
KRP Avatar asked May 20 '13 12:05

KRP


3 Answers

A solution using LINQ2XML can look like this (no classes needed):

var xml = XDocument.Parse(xmlSrc); // from XML string, e.g.: <xml ...><Persons><Person>...
//var xml = XDocument.Load(xmlFile); // from XML file, e.g.: c:\temp\persons.xml

var persons = xml.Root.Elements("Person").ToList();
var p1Addresses = persons[0].Elements("Addresses").ToList();
foreach (var address in p1Addresses.Elements("Address"))
{
    var elementAddress = address.Element("AddressType");
    var elementCity = address.Element("City");
    System.Console.WriteLine(string.Format("{0} - {1}", elementAddress.Value, elementCity.Value));
}

The output is:

BillTo - Moscow
ShipTo - Moscow
Contact - Moscow
like image 117
keenthinker Avatar answered Sep 22 '22 10:09

keenthinker


I would suggest you read this article: http://www.codeproject.com/Articles/62839/Adventures-with-C-4-0-dynamic-ExpandoObject-Elasti. There is a way to construct dynamic object from XML. Or this article: http://www.codeproject.com/Articles/461677/Creating-a-dynamic-object-from-XML-using-ExpandoOb. Take whatever you need and you can customize the code for your needs.

like image 39
Thai Anh Duc Avatar answered Sep 18 '22 10:09

Thai Anh Duc


Check this example:

        string xml =
            @"<?xml version='1.0' encoding='utf-8' ?>
              <Persons>
               <Person>
                <Id>10</Id>
                <FirstName> Dino </FirstName>
                <LastName> Esposito </LastName>
                <Addresses>
                  <Address>
                   <AddressType>BillTo</AddressType>
                   <Street1></Street1>
                   <Street2></Street2>
                   <Street3></Street3>
                   <City>Moscow</City>
                </Address>
                <Address>
                 <AddressType>ShipTo</AddressType>
                 <Street1></Street1>
                 <Street2></Street2>
                 <Street3></Street3>
                 <City>Moscow</City>
                </Address>
                <Address>
                  <AddressType>Contact</AddressType>
                  <Street1></Street1>
                  <Street2></Street2>
                  <Street3></Street3>
                  <City>Moscow</City>
                </Address>
             </Addresses>
            </Person>
           </Persons>";

        XElement root = XElement.Parse(xml);

        IEnumerable<XElement> list = root.XPathSelectElements("./Person/Addresses/Address[2]/City");
        foreach (XElement el in list)
            Console.WriteLine(el);
        Console.ReadLine();

You will get: <City>Moscow</City>

Or look at this solution using DynamicObject:

    XElement root = XElement.Parse(xml);
    dynamic persons = DynamicXml.Parse(xml);
    Console.WriteLine(persons.Person.Addresses.Address[1].City);

Deserialize XML To Object using Dynamic

like image 37
Adolfo Perez Avatar answered Sep 18 '22 10:09

Adolfo Perez