Converting Xml to a Dynamic C# Object

Deserialize XML To Object using Dynamic

You may want to try this.

string xml = @"<Students>
<Student ID=""100"">
<Name>Arul</Name>
<Mark>90</Mark>
</Student>
<Student>
<Name>Arul2</Name>
<Mark>80</Mark>
</Student>
</Students>";

dynamic students = DynamicXml.Parse(xml);

var id = students.Student[0].ID;
var name1 = students.Student[1].Name;

foreach(var std in students.Student)
{
Console.WriteLine(std.Mark);
}

public class DynamicXml : DynamicObject
{
XElement _root;
private DynamicXml(XElement root)
{
_root = root;
}

public static DynamicXml Parse(string xmlString)
{
return new DynamicXml(XDocument.Parse(xmlString).Root);
}

public static DynamicXml Load(string filename)
{
return new DynamicXml(XDocument.Load(filename).Root);
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;

var att = _root.Attribute(binder.Name);
if (att != null)
{
result = att.Value;
return true;
}

var nodes = _root.Elements(binder.Name);
if (nodes.Count() > 1)
{
result = nodes.Select(n => n.HasElements ? (object)new DynamicXml(n) : n.Value).ToList();
return true;
}

var node = _root.Element(binder.Name);
if (node != null)
{
result = node.HasElements || node.HasAttributes ? (object)new DynamicXml(node) : node.Value;
return true;
}

return true;
}
}

--EDIT--

To make it work with xml namespaces, I added RemoveNamespaces method.

public class DynamicXml : DynamicObject
{
XElement _root;
private DynamicXml(XElement root)
{
_root = root;
}

public static DynamicXml Parse(string xmlString)
{
return new DynamicXml(RemoveNamespaces(XDocument.Parse(xmlString).Root));
}

public static DynamicXml Load(string filename)
{
return new DynamicXml(RemoveNamespaces(XDocument.Load(filename).Root));
}

private static XElement RemoveNamespaces(XElement xElem)
{
var attrs = xElem.Attributes()
.Where(a => !a.IsNamespaceDeclaration)
.Select(a => new XAttribute(a.Name.LocalName, a.Value))
.ToList();

if (!xElem.HasElements)
{
XElement xElement = new XElement(xElem.Name.LocalName, attrs);
xElement.Value = xElem.Value;
return xElement;
}

var newXElem = new XElement(xElem.Name.LocalName, xElem.Elements().Select(e => RemoveNamespaces(e)));
newXElem.Add(attrs);
return newXElem;
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;

var att = _root.Attribute(binder.Name);
if (att != null)
{
result = att.Value;
return true;
}

var nodes = _root.Elements(binder.Name);
if (nodes.Count() > 1)
{
result = nodes.Select(n => n.HasElements ? (object)new DynamicXml(n) : n.Value).ToList();
return true;
}

var node = _root.Element(binder.Name);
if (node != null)
{
result = node.HasElements || node.HasAttributes ? (object)new DynamicXml(node) : node.Value;
return true;
}

return true;
}
}

convert from dynamic xml to c# object

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.

Converting XML to C# object

For such problem, i would always choose using XmlSerializer.
Use this classes:

    using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace classes
{
[XmlType(Namespace = "urn:ebay:apis:eBLBaseComponents")]
public class Order
{
public int OrderID { get; set; }
public string OrderStatus { get; set; }
}

[XmlType(Namespace = "urn:ebay:apis:eBLBaseComponents")]
public class OrderArray
{
public List<Order> Orders { get; set; }
}

[XmlRoot(Namespace = "urn:ebay:apis:eBLBaseComponents")]
public class GetOrdersResponse
{
public string Timestamp { get; set; }
public string Ack { get; set; }
public string Version { get; set; }
public string Build { get; set; }
public OrderArray OrderArray { get; set; }
}

}

Then Deserialize to your object:

XmlSerializer serializer = new XmlSerializer(typeof(GetOrdersResponse ));
using (TextReader reader = new StringReader(xmlResult))
{
GetOrdersResponse result = (GetOrdersResponse) serializer.Deserialize(reader);
}

int id=result.OrderArray.Orders.First().OrderID; //this will return ID of first object in Orders list.

How to get deserialized xml attribute from dynamic object

To deal with special characters, such as "@" in dynamic object, you must cast it to `
(IDictionary). And then you can get the recevied attribute as bellow:

var received = ((IDictionary<string, object>)obj.Message)["@recevied"];

Deserialize XML into object with dynamic child elements

I've managed to resolve this using a dynamic type when deserializing.
When I deserialize ValuesRead, it is a defined as a dynamic type.

When deserialized, it turns into an XmlNode and from there I iterate over the node use the Name and InnerText values to read all the data.

Convert XML String to Object

You need to use the xsd.exe tool which gets installed with the Windows SDK into a directory something similar to:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin

And on 64-bit computers:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin

And on Windows 10 computers:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin

On the first run, you use xsd.exe and you convert your sample XML into a XSD file (XML schema file):

xsd yourfile.xml

This gives you yourfile.xsd, which in a second step, you can convert again using xsd.exe into a C# class:

xsd yourfile.xsd /c

This should give you a file yourfile.cs which will contain a C# class that you can use to deserialize the XML file you're getting - something like:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));

Should work pretty well for most cases.

Update: the XML serializer will take any stream as its input - either a file or a memory stream will be fine:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);

or use a StringReader:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);

How to serialize dynamic object to xml c#

You can implement your own serialize object by using IXmlSerializable

[Serializable]
public class ObjectSerialize : IXmlSerializable
{
public List<object> ObjectList { get; set; }

public XmlSchema GetSchema()
{
return new XmlSchema();
}

public void ReadXml(XmlReader reader)
{

}

public void WriteXml(XmlWriter writer)
{
foreach (var obj in ObjectList)
{
//Provide elements for object item
writer.WriteStartElement("Object");
var properties = obj.GetType().GetProperties();
foreach (var propertyInfo in properties)
{
//Provide elements for per property
writer.WriteElementString(propertyInfo.Name, propertyInfo.GetValue(obj).ToString());
}
writer.WriteEndElement();
}
}
}

Usage;

        var output = new List<object>
{
new { Sample = "Sample" }
};
var objectSerialize = new ObjectSerialize
{
ObjectList = output
};
XmlSerializer xsSubmit = new XmlSerializer(typeof(ObjectSerialize));
var xml = "";

using (var sww = new StringWriter())
{
using (XmlWriter writers = XmlWriter.Create(sww))
{
try
{
xsSubmit.Serialize(writers, objectSerialize);
}
catch (Exception ex)
{

throw;
}
xml = sww.ToString(); // Your XML
}
}

Output

<?xml version="1.0" encoding="utf-16"?>
<ObjectSerialize>
<Object>
<Sample>Sample</Sample>
</Object>
</ObjectSerialize>

Note : Be careful with that, if you want to deserialize with same type
(ObjectSerialize) you should provide ReadXml. And if you want to
specify schema, you should provide GetSchema too.

C# Parse Dynamic xML into objects and return as JSON

  1. Read the documentation,
  2. You can use XmlDocument and use ValidationType.DTD in DTD processing with XmlReaderSettings to parse and validate XML document agains DTDs
  3. Look into simiar question here
  4. You can use NewtonSoft JSON serialization library to serialize objects into JSON format
  5. Additionally, you can use dynamically generated JSON,
class cXMLJsonNode : Dictionary<string,object> 
{
}

to create custom built JSON object:

JsonConvert.SerializeObject(new cXMLJsonNode {
{ key1, value1 },
{ key2, value2 },
{ property1, new cXMLJsonNode {
{ key1, oldValue1 }
{ key2, oldValue1 }
},
{ property2, new cXMLJsonNode {
{ key1, newValue1 }
{ key2, new cXMLJsonNode {
{ key1, newValue1 }
{ key2, newValue2 }
}
},
})


Related Topics



Leave a reply



Submit