¿Cómo convertir JSON a XML o XML a JSON en C#?
Empecé a usar Json.NET para convertir una cadena en formato JSON a objeto o viceversa. No estoy seguro en el marco Json.NET, ¿es posible convertir una cadena en formato JSON a XML y viceversa?
Sí. Usando la clase JsonConvert que contiene métodos auxiliares para este propósito preciso:
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
Documentación aquí: Conversión entre JSON y XML con Json.NET
Sí, puedes hacerlo (yo lo hago), pero ten en cuenta algunas paradojas al realizar la conversión y manéjalas adecuadamente. No puede adaptarse automáticamente a todas las posibilidades de la interfaz y existe un soporte integrado limitado para controlar la conversión; muchas estructuras y valores JSON no se pueden convertir automáticamente en ambos sentidos. Tenga en cuenta que estoy usando la configuración predeterminada con la biblioteca Newtonsoft JSON y la biblioteca MS XML, por lo que su kilometraje puede variar:
XML -> JSON
- Todos los datos se convierten en datos de cadena (por ejemplo, siempre obtendrá "falso", no falso o "0", no 0 ). Obviamente, JavaScript los trata de manera diferente en ciertos casos.
- Los elementos secundarios pueden convertirse en objetos anidados
{}
O en matrices anidadas[ {} {} ...]
dependiendo de si solo hay uno o más de un elemento secundario XML. Consumiría estos dos de manera diferente en JavaScript, etc. Diferentes ejemplos de XML que se ajustan al mismo esquema pueden producir estructuras JSON realmente diferentes de esta manera. Puede agregar el atributo json:Array='true' a su elemento para solucionar este problema en algunos (pero no necesariamente en todos) los casos. - Su XML debe estar bastante bien formado, he notado que no es necesario que se ajuste perfectamente al estándar W3C, pero 1. debe tener un elemento raíz y 2. no puede comenzar los nombres de los elementos con números son dos de los estándares XML aplicados. Lo he encontrado al usar las bibliotecas Newtonsoft y MS.
- En versiones anteriores, los elementos en blanco no se convierten a JSON. Son ignorados. Un elemento en blanco no se convierte en "elemento": nulo
Una nueva actualización cambia la forma en que se pueden manejar los valores nulos (gracias a Jon Story por señalarlo): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON -> XML
- Necesita un objeto de nivel superior que se convierta en un elemento XML raíz o el analizador fallará.
- Los nombres de sus objetos no pueden comenzar con un número, ya que no se pueden convertir en elementos (XML es técnicamente incluso más estricto que esto), pero puedo "salirme con la mía" rompiendo algunas de las otras reglas de nomenclatura de elementos.
No dude en mencionar cualquier otro problema que haya notado. He desarrollado mis propias rutinas personalizadas para preparar y limpiar las cuerdas mientras convierto de un lado a otro. Su situación puede requerir o no preparación/limpieza. Como menciona StaxMan, su situación puede requerir que convierta entre objetos... esto podría implicar interfaces apropiadas y un montón de declaraciones de casos, etc. para manejar las advertencias que menciono anteriormente.
Puedes realizar estas conversiones también con .NET Framework:
JSON a XML: usando System.Runtime.Serialization.Json
var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
XML a JSON: mediante System.Web.Script.Serialization
var json = new JavaScriptSerializer().Serialize(GetXmlData(XElement.Parse(xmlString)));
private static Dictionary<string, object> GetXmlData(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 => GetXmlData(e)));
else if (!xml.IsEmpty) attr.Add("_value", xml.Value);
return new Dictionary<string, object> { { xml.Name.LocalName, attr } };
}
No estoy seguro de que tal conversión tenga sentido (sí, muchos lo hacen, pero principalmente para forzar una clavija cuadrada a través de un orificio redondo): hay una falta de coincidencia de impedancia estructural y la conversión genera pérdidas. Por lo tanto, desaconsejaría este tipo de transformaciones de formato a formato.
Pero si lo hace, primero convierta de json a objeto, luego de objeto a xml (y viceversa para la dirección inversa). Realizar una transformación directa conduce a resultados desagradables, pérdida de información o posiblemente ambas cosas.