¿Cómo convertir XML a JSON usando C # / LINQ?

Tengo el siguiente archivo XML que necesito convertir a JSON en el servidor. Inicialmente pensé que lo convertiría en un Diccionario y luego usaría el JavaScriptSerializer para convertirlo en JSON, pero dado que cada columna podría tener un tipo de valor diferente, no creo que funcione. ¿Alguien ha hecho algo similar anteriormente en C # / LINQ?

Necesito preservar los Tipos de Valor (Booleanos, Cadenas, Entero) de cada columna.

Agradecería cualquier consejo sobre esto ya que estoy empezando a trabajar con XML. Gracias.

 True Hello World 999  

 using System; using System.Linq; using System.Web.Script.Serialization; using System.Xml.Linq; class Program { static void Main() { var xml = @" True Hello World 999 "; var dic = XDocument .Parse(xml) .Descendants("Column") .ToDictionary( c => c.Attribute("Name").Value, c => c.Value ); var json = new JavaScriptSerializer().Serialize(dic); Console.WriteLine(json); } } 

produce:

 {"key1":"True","key2":"Hello World","key3":"999"} 

Obviamente, esto trata todos los valores como cadenas. Si desea mantener la semántica del tipo subyacente, puede hacer lo siguiente:

 using System; using System.Linq; using System.Web.Script.Serialization; using System.Xml.Linq; class Program { static void Main() { var xml = @" True Hello World 999 "; var dic = XDocument .Parse(xml) .Descendants("Column") .ToDictionary( c => c.Attribute("Name").Value, c => Convert.ChangeType( c.Value, typeof(string).Assembly.GetType(c.Attribute("DataType").Value, true) ) ); var json = new JavaScriptSerializer().Serialize(dic); Console.WriteLine(json); } } 

produce:

 {"key1":true,"key2":"Hello World","key3":999} 

Y si no puede modificar la estructura XML subyacente, necesitará una función personalizada que convierta entre sus tipos personalizados y el tipo .NET subyacente:

 using System; using System.Linq; using System.Web.Script.Serialization; using System.Xml.Linq; class Program { static void Main() { var xml = @" True Hello World 999 "; var dic = XDocument .Parse(xml) .Descendants("Column") .ToDictionary( c => c.Attribute("Name").Value, c => Convert.ChangeType( c.Value, GetType(c.Attribute("DataType").Value) ) ); var json = new JavaScriptSerializer().Serialize(dic); Console.WriteLine(json); } private static Type GetType(string type) { switch (type) { case "Integer": return typeof(int); case "String": return typeof(string); case "Boolean": return typeof(bool); // TODO: add any other types that you want to support default: throw new NotSupportedException( string.Format("The type {0} is not supported", type) ); } } } 

¿Es necesario usar LINQ? De lo contrario, puedes intentar esto:

 XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); string jsonText = JsonConvert.SerializeXmlNode(doc); 

Tomado de esta publicación .

Para la anidación profunda de elementos XML con más y atributos desconocidos, puede utilizar esta recursión:

 private static string XmlToJson(string xmlString) { return new JavaScriptSerializer().Serialize(GetXmlValues(XElement.Parse(xmlString))); } private static Dictionary GetXmlValues(XElement xml) { var attr = xml.Attributes().ToDictionary(d => d.Name.LocalName, d => (object)d.Value); if (xml.HasElements) attr.Add("_value", xml.Elements().Select(e => GetXmlValues(e))); else if (!xml.IsEmpty) attr.Add("_value", xml.Value); return new Dictionary { { xml.Name.LocalName, attr } }; } 

Para su ejemplo, el resultado será:

 { "Columns":{ "_value":[ { "Column":{ "Name":"key1", "DataType":"Boolean", "_value":"True" } }, { "Column":{ "Name":"key2", "DataType":"String", "_value":"Hello World" } }, { "Column":{ "Name":"key3", "DataType":"Integer", "_value":"999" } } ] } } 

Y para casos XML más complejos como este , puede verificar el análogo JSON aquí .