xmlnodeconverter with that only newtonsoft jsonconvert convertir convert begins c# json xml json.net

c# - with - ¿Cómo convertir JSON a XML o XML a JSON?



xml to json c# (12)

Comencé a usar Json.NET para convertir una cadena en formato JSON a objeto o viceversa. No estoy seguro en el marco de Json.NET, ¿es posible convertir una cadena en formato JSON a XML y viceversa?


Aquí está el código completo de c # para convertir xml a json

public static class JSon { public static string XmlToJSON(string xml) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); return XmlToJSON(doc); } public static string XmlToJSON(XmlDocument xmlDoc) { StringBuilder sbJSON = new StringBuilder(); sbJSON.Append("{ "); XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true); sbJSON.Append("}"); return sbJSON.ToString(); } // XmlToJSONnode: Output an XmlElement, possibly as part of a higher array private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName) { if (showNodeName) sbJSON.Append("/"" + SafeJSON(node.Name) + "/": "); sbJSON.Append("{"); // Build a sorted list of key-value pairs // where key is case-sensitive nodeName // value is an ArrayList of string or XmlElement // so that we know whether the nodeName is an array or not. SortedList<string, object> childNodeNames = new SortedList<string, object>(); // Add in all node attributes if (node.Attributes != null) foreach (XmlAttribute attr in node.Attributes) StoreChildNode(childNodeNames, attr.Name, attr.InnerText); // Add in all nodes foreach (XmlNode cnode in node.ChildNodes) { if (cnode is XmlText) StoreChildNode(childNodeNames, "value", cnode.InnerText); else if (cnode is XmlElement) StoreChildNode(childNodeNames, cnode.Name, cnode); } // Now output all stored info foreach (string childname in childNodeNames.Keys) { List<object> alChild = (List<object>)childNodeNames[childname]; if (alChild.Count == 1) OutputNode(childname, alChild[0], sbJSON, true); else { sbJSON.Append(" /"" + SafeJSON(childname) + "/": [ "); foreach (object Child in alChild) OutputNode(childname, Child, sbJSON, false); sbJSON.Remove(sbJSON.Length - 2, 2); sbJSON.Append(" ], "); } } sbJSON.Remove(sbJSON.Length - 2, 2); sbJSON.Append(" }"); } // StoreChildNode: Store data associated with each nodeName // so that we know whether the nodeName is an array or not. private static void StoreChildNode(SortedList<string, object> childNodeNames, string nodeName, object nodeValue) { // Pre-process contraction of XmlElement-s if (nodeValue is XmlElement) { // Convert <aa></aa> into "aa":null // <aa>xx</aa> into "aa":"xx" XmlNode cnode = (XmlNode)nodeValue; if (cnode.Attributes.Count == 0) { XmlNodeList children = cnode.ChildNodes; if (children.Count == 0) nodeValue = null; else if (children.Count == 1 && (children[0] is XmlText)) nodeValue = ((XmlText)(children[0])).InnerText; } } // Add nodeValue to ArrayList associated with each nodeName // If nodeName doesn''t exist then add it List<object> ValuesAL; if (childNodeNames.ContainsKey(nodeName)) { ValuesAL = (List<object>)childNodeNames[nodeName]; } else { ValuesAL = new List<object>(); childNodeNames[nodeName] = ValuesAL; } ValuesAL.Add(nodeValue); } private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName) { if (alChild == null) { if (showNodeName) sbJSON.Append("/"" + SafeJSON(childname) + "/": "); sbJSON.Append("null"); } else if (alChild is string) { if (showNodeName) sbJSON.Append("/"" + SafeJSON(childname) + "/": "); string sChild = (string)alChild; sChild = sChild.Trim(); sbJSON.Append("/"" + SafeJSON(sChild) + "/""); } else XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName); sbJSON.Append(", "); } // Make a string safe for JSON private static string SafeJSON(string sIn) { StringBuilder sbOut = new StringBuilder(sIn.Length); foreach (char ch in sIn) { if (Char.IsControl(ch) || ch == ''/''') { int ich = (int)ch; sbOut.Append(@"/u" + ich.ToString("x4")); continue; } else if (ch == ''/"'' || ch == ''//' || ch == ''/'') { sbOut.Append(''//'); } sbOut.Append(ch); } return sbOut.ToString(); } }

Para convertir una cadena XML dada a JSON, simplemente llame a la función XmlToJSON () como se muestra a continuación.

string xml = "<menu id=/"file/" value=/"File/"> " + "<popup>" + "<menuitem value=/"New/" onclick=/"CreateNewDoc()/" />" + "<menuitem value=/"Open/" onclick=/"OpenDoc()/" />" + "<menuitem value=/"Close/" onclick=/"CloseDoc()/" />" + "</popup>" + "</menu>"; string json = JSON.XmlToJSON(xml); // json = { "menu": {"id": "file", "popup": { "menuitem": [ {"onclick": "CreateNewDoc()", "value": "New" }, {"onclick": "OpenDoc()", "value": "Open" }, {"onclick": "CloseDoc()", "value": "Close" } ] }, "value": "File" }}


Aquí hay un fragmento de código simple que convierte un XmlNode (recursivamente) en una tabla hash, y agrupa varias instancias del mismo hijo en una matriz (como una ArrayList). La Hashtable generalmente se acepta para convertir en JSON por la mayoría de las bibliotecas JSON.

protected object convert(XmlNode root){ Hashtable obj = new Hashtable(); for(int i=0,n=root.ChildNodes.Count;i<n;i++){ object result = null; XmlNode current = root.ChildNodes.Item(i); if(current.NodeType != XmlNodeType.Text) result = convert(current); else{ int resultInt; double resultFloat; bool resultBoolean; if(Int32.TryParse(current.Value, out resultInt)) return resultInt; if(Double.TryParse(current.Value, out resultFloat)) return resultFloat; if(Boolean.TryParse(current.Value, out resultBoolean)) return resultBoolean; return current.Value; } if(obj[current.Name] == null) obj[current.Name] = result; else if(obj[current.Name].GetType().Equals(typeof(ArrayList))) ((ArrayList)obj[current.Name]).Add(result); else{ ArrayList collision = new ArrayList(); collision.Add(obj[current.Name]); collision.Add(result); obj[current.Name] = collision; } } return obj; }


Busqué por mucho tiempo encontrar un código alternativo a la solución aceptada con la esperanza de no usar un ensamblaje / proyecto externo. Se me ocurrió lo siguiente gracias al código fuente del proyecto DynamicJson :

public XmlDocument JsonToXML(string json) { XmlDocument doc = new XmlDocument(); using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max)) { XElement xml = XElement.Load(reader); doc.LoadXml(xml.ToString()); } return doc; }

Nota: Quería un XmlDocument en lugar de un XElement para fines de xPath. Además, este código, obviamente, solo va de JSON a XML, hay varias formas de hacer lo contrario.


Gracias por la respuesta de David Brown. En mi caso de JSON.Net 3.5, los métodos de conversión están bajo la clase estática JsonConvert:

XmlNode myXmlNode = JsonConvert.DeserializeXmlNode(myJsonString); // is node not note // or .DeserilizeXmlNode(myJsonString, "root"); // if myJsonString does not have a root string jsonString = JsonConvert.SerializeXmlNode(myXmlNode);


He utilizado los siguientes métodos para convertir JSON a XML

List<Item> items; public void LoadJsonAndReadToXML() { using (StreamReader r = new StreamReader(@"E:/Json/overiddenhotelranks.json")) { string json = r.ReadToEnd(); items = JsonConvert.DeserializeObject<List<Item>>(json); ReadToXML(); } }

y

public void ReadToXML() { try { var xEle = new XElement("Items", from item in items select new XElement("Item", new XElement("mhid", item.mhid), new XElement("hotelName", item.hotelName), new XElement("destination", item.destination), new XElement("destinationID", item.destinationID), new XElement("rank", item.rank), new XElement("toDisplayOnFod", item.toDisplayOnFod), new XElement("comment", item.comment), new XElement("Destinationcode", item.Destinationcode), new XElement("LoadDate", item.LoadDate) )); xEle.Save("E://employees.xml"); Console.WriteLine("Converted to XML"); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); }

He usado la clase llamada Item para representar los elementos

public class Item { public int mhid { get; set; } public string hotelName { get; set; } public string destination { get; set; } public int destinationID { get; set; } public int rank { get; set; } public int toDisplayOnFod { get; set; } public string comment { get; set; } public string Destinationcode { get; set; } public string LoadDate { get; set; } }

Funciona....


Me gustó lo que dijo David Brown pero obtuve la siguiente excepción.

$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException

Una solución sería modificar el archivo XML con un elemento raíz, pero eso no siempre es necesario y para una secuencia XML tampoco podría ser posible. Mi solución a continuación:

var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"../../App_Data")); var directoryInfo = new DirectoryInfo(path); var fileInfos = directoryInfo.GetFiles("*.xml"); foreach (var fileInfo in fileInfos) { XmlDocument doc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; using (XmlReader reader = XmlReader.Create(fileInfo.FullName, settings)) { while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { var node = doc.ReadNode(reader); string json = JsonConvert.SerializeXmlNode(node); } } } }

Ejemplo XML que genera el error:

<parent> <child> Text </child> </parent> <parent> <child> <grandchild> Text </grandchild> <grandchild> Text </grandchild> </child> <child> Text </child> </parent>


No estoy seguro de que haya un punto en dicha conversión (sí, muchos lo hacen, pero principalmente para forzar una clavija cuadrada a través del orificio redondo): existe una falta de coincidencia de impedancia estructural y la conversión tiene pérdidas. Así que recomendaría contra tales 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). Hacer una transformación directa conduce a resultados feos, pérdida de información o posiblemente a ambos.


Prueba esta función. Simplemente lo escribí y no he tenido muchas oportunidades de probarlo, pero mis pruebas preliminares son prometedoras.

public static XmlDocument JsonToXml(string json) { XmlNode newNode = null; XmlNode appendToNode = null; XmlDocument returnXmlDoc = new XmlDocument(); returnXmlDoc.LoadXml("<Document />"); XmlNode rootNode = returnXmlDoc.SelectSingleNode("Document"); appendToNode = rootNode; string[] arrElementData; string[] arrElements = json.Split(''/r''); foreach (string element in arrElements) { string processElement = element.Replace("/r", "").Replace("/n", "").Replace("/t", "").Trim(); if ((processElement.IndexOf("}") > -1 || processElement.IndexOf("]") > -1) && appendToNode != rootNode) { appendToNode = appendToNode.ParentNode; } else if (processElement.IndexOf("[") > -1) { processElement = processElement.Replace(":", "").Replace("[", "").Replace("/"", "").Trim(); newNode = returnXmlDoc.CreateElement(processElement); appendToNode.AppendChild(newNode); appendToNode = newNode; } else if (processElement.IndexOf("{") > -1 && processElement.IndexOf(":") > -1) { processElement = processElement.Replace(":", "").Replace("{", "").Replace("/"", "").Trim(); newNode = returnXmlDoc.CreateElement(processElement); appendToNode.AppendChild(newNode); appendToNode = newNode; } else { if (processElement.IndexOf(":") > -1) { arrElementData = processElement.Replace(": /"", ":").Replace("/",", "").Replace("/"", "").Split('':''); newNode = returnXmlDoc.CreateElement(arrElementData[0]); for (int i = 1; i < arrElementData.Length; i++) { newNode.InnerText += arrElementData[i]; } appendToNode.AppendChild(newNode); } } } return returnXmlDoc; }


Puedes hacer estas conversiones también con .NET Framework:

JSON a XML: utilizando System.Runtime.Serialization.Json

var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader( Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));

XML a JSON: utilizando 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 } }; }


Sí, puedes hacerlo (yo lo hago), pero ten en cuenta algunas paradojas al realizar la conversión y resuélvelas adecuadamente. No puede ajustarse automáticamente a todas las posibilidades de la interfaz, y hay un soporte incorporado 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

  1. 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.
  2. Los elementos secundarios pueden convertirse en objeto anidado {} O en matriz anidada [ {} {} ...] dependiendo de si solo hay uno o más de un elemento secundario XML. Consumiría estos dos de manera diferente en JavaScript, etc. Los 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 esto en algunos casos (pero no necesariamente en todos).
  3. Su XML debe estar bien formado, me he dado cuenta de que no es necesario que se adapte 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 exigidos He encontrado al usar Newtonsoft y MS bibliotecas.
  4. Los elementos en blanco no se convierten a JSON. Ellos son ignorados. Un elemento en blanco no se convierte en "elemento": nulo

JSON -> XML

  1. Necesita un objeto de nivel superior que se convertirá en un elemento XML raíz o el analizador fallará.
  2. 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 suya" de romper algunas de las otras reglas de nombres de elementos.

Siéntase libre de mencionar cualquier otro problema que haya notado, he desarrollado mis propias rutinas personalizadas para preparar y limpiar las cuerdas mientras las convierto de un lado a otro. Su situación puede o no requerir una preparación / limpieza. Como menciona StaxMan, su situación puede requerir que usted convierta entre objetos ... esto podría implicar interfaces apropiadas y un montón de declaraciones de casos / etc para manejar las advertencias que mencioné anteriormente.


Sí. Usando la clase JsonConvert que contiene métodos de ayuda 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


Cinchoo ETL : una biblioteca de código abierto disponible para realizar la conversión de Xml a JSON fácilmente con pocas líneas de código

Xml -> JSON:

using (var p = new ChoXmlReader("sample.xml")) { using (var w = new ChoJSONWriter("sample.json")) { w.Write(p); } }

JSON -> Xml:

using (var p = new ChoJsonReader("sample.json")) { using (var w = new ChoXmlWriter("sample.xml")) { w.Write(p); } }

Consulte el artículo de CodeProject para obtener ayuda adicional.

Descargo de responsabilidad: Soy el autor de esta biblioteca.