Reputation: 1996
Following is the XML string which we are trying to convert in to JSON string.
<?xml version="1.0" encoding="utf-16" ?>
<MyClass>
<Id>1</Id>
<Names>
<string>Surya</string>
<string>Kiran</string>
</Names>
<ClassTypes>
<Types>
<TypeId>1</TypeId>
<TypeName>First Name</TypeName>
</Types>
<Types>
<TypeId>2</TypeId>
<TypeName>Last Name</TypeName>
</Types>
</ClassTypes>
<Status>1</Status>
</MyClass>
using the following code, I am getting the result as below
xmlString = "<?xml version=\"1.0\" encoding=\"utf-16\"?><MyClass><Id>1</Id><Names><string>Surya</string><string>Kiran</string></Names><ClassTypes><Types><TypeId>1</TypeId><TypeName>First Name</TypeName></Types><Types><TypeId>2</TypeId><TypeName>Last Name</TypeName></Types></ClassTypes><Status>1</Status></MyClass>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
doc.ChildNodes.OfType<XmlNode>().Where(x => x.NodeType == XmlNodeType.XmlDeclaration).ToList().ForEach(x => doc.RemoveChild(x));
jsonString = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.None, true);
Actual Result
{"Id":"1","Names":{"string":["Surya","Kiran"]},"ClassTypes":{"Types":[{"TypeId":"1","TypeName":"First Name"},{"TypeId":"2","TypeName":"Last Name"}]},"Status":"1"}
Expected Result
{"Id":1,"Names":["Surya","Kiran"],"ClassTypes":[{"TypeId":1,"TypeName":"First Name"},{"TypeId":2,"TypeName":"Last Name"}],"Status":0}
We would require this result for deserialization to the below class
public class MyClass
{
public int Id { get; set; }
public IList<string> Names { get; protected set; }
public IList<Types> ClassTypes { get; protected set; }
public StatusType Status { get; set; }
public MyClass()
{
Names = new List<string>();
ClassTypes = new List<Types>();
Status = StatusType.Active;
}
}
public class Types
{
public int TypeId { get; set; }
public string TypeName { get; set; }
}
public enum StatusType
{
Active = 0,
InActive = 1
}
Upvotes: 0
Views: 672
Reputation: 10078
You can use linq-to-xml. Try this code
var xmlString = "<?xml version=\"1.0\" encoding=\"utf-16\"?><MyClass><Id>1</Id><Names><string>Surya</string><string>Kiran</string></Names><ClassTypes><Types><TypeId>1</TypeId><TypeName>First Name</TypeName></Types><Types><TypeId>2</TypeId><TypeName>Last Name</TypeName></Types></ClassTypes><Status>1</Status></MyClass>";
XDocument doc = XDocument.Parse(xmlString);
XNode xNode = doc.FirstNode;
var jsonString = Newtonsoft.Json.JsonConvert.SerializeXNode(xNode, Newtonsoft.Json.Formatting.Indented, true);
Json string will be this
{
"Id": "1",
"Names": {
"string": [
"Surya",
"Kiran"
]
},
"ClassTypes": {
"Types": [
{
"TypeId": "1",
"TypeName": "First Name"
},
{
"TypeId": "2",
"TypeName": "Last Name"
}
]
},
"Status": "1"
}
UPDATE
Since OP has updated the question with classes, here is the alternative approach.
You can get properly formatted JSON with this code
var xmlString = "<?xml version=\"1.0\" encoding=\"utf-16\"?><MyClass><Id>1</Id><Names><string>Surya</string><string>Kiran</string></Names><ClassTypes><Types><TypeId>1</TypeId><TypeName>First Name</TypeName></Types><Types><TypeId>2</TypeId><TypeName>Last Name</TypeName></Types></ClassTypes><Status>1</Status></MyClass>";
var myClassObject = XmlDeserializeData<MyClass>(xmlString);
var jsonString = JsonSerializeData(myClassObject);
Here are my generic serialize/deserialize methods:
//using System.Xml.Serialization;
public T XmlDeserializeData<T>(string data)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringReader reader = new StringReader(data);
T result = (T)serializer.Deserialize(reader);
return result;
}
//using Newtonsoft.Json
public string JsonSerializeData<T>(T data)
{
var serializedData = Newtonsoft.Json.JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter());
return serializedData; //notice the new Newtonsoft.Json.Converters.StringEnumConverter() to serialize enum as string
}
But, before this, you need to make following changes in your class
public class MyClass
{
public int Id { get; set; }
public List<string> Names { get; protected set; } //notice I changed from IList to List
public List<Types> ClassTypes { get; protected set; } //IList doesn't work out of the box
public StatusType Status { get; set; }
public MyClass()
{
Names = new List<string>();
ClassTypes = new List<Types>();
Status = StatusType.Active;
}
}
public enum StatusType //notice I added XmlEnum attribute, to serialize as 0, 1
{
[XmlEnum(Name = "0")]
Active = 0,
[XmlEnum(Name = "1")]
InActive = 1
}
And here is the generated JSON
{
"Id": 1,
"Names": [
"Surya",
"Kiran"
],
"ClassTypes": [
{
"TypeId": 1,
"TypeName": "First Name"
},
{
"TypeId": 2,
"TypeName": "Last Name"
}
],
"Status": "InActive"
}
UPDATE 2
Since you can not change the classes, and your XML is not 'ideal', you can do the following to get the desired JSON.
var xmlString = "<?xml version=\"1.0\" encoding=\"utf-16\"?><MyClass><Id>1</Id><Names><string>Surya</string><string>Kiran</string></Names><ClassTypes><Types><TypeId>1</TypeId><TypeName>First Name</TypeName></Types><Types><TypeId>2</TypeId><TypeName>Last Name</TypeName></Types></ClassTypes><Status>1</Status></MyClass>";
xmlString = xmlString.Replace("<ClassTypes>", "")
.Replace("</ClassTypes>", "")
.Replace("<Names>", "")
.Replace("</Names>", "");
xmlString = xmlString.Replace("<Types>", "<ClassTypes>")
.Replace("</Types>", "</ClassTypes>")
.Replace("<string>", "<Names>")
.Replace("</string>", "</Names>");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
var xmlNode = xmlDoc.SelectNodes("//MyClass").Item(0);
var jsonString = Newtonsoft.Json.JsonConvert.SerializeXmlNode(xmlNode, Newtonsoft.Json.Formatting.Indented, true);
Note It will generate the desired json, BUT this is a ugly hack! Either of the previous methods should be used.
Upvotes: 2