Comencé 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?
Tenga en cuenta como dijo StaxMan, si hay ex. espacio en el nodo del elemento, será ignorado por xml. Por ej. "Identificación del alumno": 11000 no estará en el resultado xcuz de espacio en el nombre de la propiedad. xml no acepta tener espacio dentro del nodo del elemento.
Daniel B
Respuestas:
424
Si. 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 =newXmlDocument();
doc.LoadXml(xml);string jsonText =JsonConvert.SerializeXmlNode(doc);// To convert JSON text contained in string json into an XML nodeXmlDocument doc =JsonConvert.DeserializeXmlNode(json);
Solo para tu información, hay un problema potencial aquí. Cuando estaba convirtiendo una matriz de nodos xml en json, estaba haciendo una matriz en json. Pero, cuando ejecuto una matriz de nodos xml que tienen un recuento de 1, entonces la conversión json ya no formatea una matriz. Aquí se pierde una matriz xml con un solo elemento en la traducción.
Levitikon
3
Sorpresa sorpresa: esta es la impedancia entre XML y JSON, y la razón por la cual (IMO) no es una buena idea convertir directamente entre los dos. Pero, oye, hay muchos desarrolladores que están muy en desacuerdo aquí (según los votos negativos en mi respuesta) y no les importa estas conversiones de datos accidentales o la posible pérdida de datos ...
StaxMan
77
@StaxMan: Creo que todos pueden estar de acuerdo en que no hay una forma estandarizada de representar un documento XML en formato JSON. Su respuesta probablemente fue rechazada porque en realidad no respondió la pregunta. El OP no estaba preguntando si debería hacer la conversión, sino más bien si podría hacerlo utilizando las herramientas que ya están a su disposición.
David Brown
46
Sí, puede hacerlo (lo hago), pero tenga en cuenta algunas paradojas al convertir y maneje adecuadamente. No puede ajustarse automáticamente a todas las posibilidades de la interfaz, y hay 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 {} anidados O en matrices anidadas, [ {} {} ...]dependiendo de si solo hay uno o más de un elemento hijo 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 esto en algunos (pero no necesariamente todos) los casos.
Su XML debe estar bastante bien formado, he notado que no necesita ajustarse 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 forzados 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 "elemento": nulo
Necesita un objeto de nivel superior que se convertirá 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 pueden convertirse en elementos (XML es técnicamente aún más estricto que esto), pero puedo 'salirse' con romper algunas de las otras reglas de nomenclatura de elementos.
Por favor, siéntase libre de mencionar cualquier otro problema que haya notado, he desarrollado mis propias rutinas personalizadas para preparar y limpiar las cadenas a medida que convierto de un lado a otro. Su situación puede o no requerir 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.
¡Esta! Buena elaboración de en qué se basó mi respuesta corta (y muy rechazada en algún momento): hay muchas, muchas trampas si haces una conversión directa ciega. Puede que no estén bloqueando problemas para un uso específico, pero también pueden ser muy desagradables para otros.
StaxMan
1
Con respecto al n. ° 4 en XML -> JSON: puede usar la propiedad NullValueHandling para especificar que los valores nulos se deben incluir explícitamente - newtonsoft.com/json/help/html/…
Jon Story
La descripción del problema en este comentario se aplica bien a TODAS las implementaciones de algoritmos que convierten JSON a XML o al revés. Una vez que uno acepta que no es posible lograr simultáneamente una fidelidad bidireccional perfecta, y al mismo tiempo, entrada y salida de "parte" o "restricción" (esquema / formato dictado). - En el caso general.
DALDEI
33
Puede hacer estas conversiones también con .NET Framework:
Aparece un error en GetXmlData "El nombre 'GetXmlData' no existe en el contexto actual" ¿Hay una directiva de uso que me falta?
TimSmith-Aardwolf
44
@ TimSmith-Aardwolf, aquí está todo el código que necesita. Para usar System.Web.Script.Serialization necesita agregar el ensamblado System.Web.Extensions en Referencias.
Termininja
@Termininja, JSON a XML dándome tipo también, ¿cómo eliminar eso?
galleta
@Termininja, perfecto, gracias.
galleta
30
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): hay un desajuste de impedancia estructural y la conversión es con pérdida. Por lo tanto, 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 ambos.
Aunque tu respuesta se rompió, me alegro de que esté aquí. Quiero hacer la conversión y estaba considerando omitir los objetos intermedios de c #, pero ahora no estoy tan seguro. De lo contrario, necesitaría generar objetos c # basados en el XSD y dado que sería solo para fines de conversión, parecía una capa desperdiciada (y esfuerzo). Si tiene ejemplos o más detalles de cómo es con pérdida, sería genial verlo.
CRice el
No sé por qué esto fue rechazado. Actualmente estoy arreglando un montón de errores relacionados con varios pasos de transformación XML <-> JSON en un producto que tenemos. La mayoría se debe a la pérdida de tipos numéricos al convertir de JSON a XML.
rikkit
La dura verdad, respuesta útil.
FailedUnitTest
@CRice Años demasiado tarde, pero tener los objetos de transferencia conserva el esquema XML, hasta cierto punto. Por ejemplo, tal como lo menciona Levitikon , si intenta convertir un documento XML con una matriz de un solo elemento, el convertidor JSON no puede saber que es una matriz a menos que provenga de un objeto de transferencia con un tipo de matriz.
jpaugh
1
El XmlNodeConverter de Newtonsoft.JSON tiene una opción de configuración para evitar este problema al transferir de JSON a XML de nuevo a JSON, pero no puede detectar casos en los que el formato original es XML
jpaugh
27
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 rootstring jsonString =JsonConvert.SerializeXmlNode(myXmlNode);
Si sus datos son una matriz, entonces necesita hacer algo como esto: JsonConvert.DeserializeXmlNode ("{\" Row \ ":" + json + "}", "root"). ToXmlString () de lo contrario obtendrá un "XmlNodeConverter solo puede convertir JSON que comienza con un objeto ". excepción.
Mitchell Skurnik
Sí, y no puedes comenzar con un número. JsonConvert.DeserializeXmlNode ("{\" 1Row \ ":" + json + "}", "root"). ToXmlString () fallará
DaFi4
la respuesta anterior y el comentario de @mitchell me ayudan ... gracias
Ajay2707
8
Busqué durante mucho tiempo para 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 :
publicXmlDocumentJsonToXML(string json){XmlDocument doc =newXmlDocument();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.
Necesitaba hacer esto recientemente en un SQLCLR y no podía tomar una dependencia, así que solo mordí la viñeta y escribí esta rutina de conversión de json a xml , fue sorprendentemente simple y solo alrededor de 20 líneas de código.
gordy
¿Cómo eliminar Typr de XML?
galleta
6
Aquí está el código completo de c # para convertir xml a json
publicstaticclassJSon{publicstaticstringXmlToJSON(string xml){XmlDocument doc =newXmlDocument();
doc.LoadXml(xml);returnXmlToJSON(doc);}publicstaticstringXmlToJSON(XmlDocument xmlDoc){StringBuilder sbJSON =newStringBuilder();
sbJSON.Append("{ ");XmlToJSONnode(sbJSON, xmlDoc.DocumentElement,true);
sbJSON.Append("}");return sbJSON.ToString();}// XmlToJSONnode: Output an XmlElement, possibly as part of a higher arrayprivatestaticvoidXmlToJSONnode(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 =newSortedList<string,object>();// Add in all node attributesif(node.Attributes!=null)foreach(XmlAttribute attr in node.Attributes)StoreChildNode(childNodeNames, attr.Name, attr.InnerText);// Add in all nodesforeach(XmlNode cnode in node.ChildNodes){if(cnode isXmlText)StoreChildNode(childNodeNames,"value", cnode.InnerText);elseif(cnode isXmlElement)StoreChildNode(childNodeNames, cnode.Name, cnode);}// Now output all stored infoforeach(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(objectChildin 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.privatestaticvoidStoreChildNode(SortedList<string,object> childNodeNames,string nodeName,object nodeValue){// Pre-process contraction of XmlElement-sif(nodeValue isXmlElement){// 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;elseif(children.Count==1&&(children[0]isXmlText))
nodeValue =((XmlText)(children[0])).InnerText;}}// Add nodeValue to ArrayList associated with each nodeName// If nodeName doesn't exist then add itList<object>ValuesAL;if(childNodeNames.ContainsKey(nodeName)){ValuesAL=(List<object>)childNodeNames[nodeName];}else{ValuesAL=newList<object>();
childNodeNames[nodeName]=ValuesAL;}ValuesAL.Add(nodeValue);}privatestaticvoidOutputNode(string childname,object alChild,StringBuilder sbJSON,bool showNodeName){if(alChild ==null){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");
sbJSON.Append("null");}elseif(alChild isstring){if(showNodeName)
sbJSON.Append("\""+SafeJSON(childname)+"\": ");string sChild =(string)alChild;
sChild = sChild.Trim();
sbJSON.Append("\""+SafeJSON(sChild)+"\"");}elseXmlToJSONnode(sbJSON,(XmlElement)alChild, showNodeName);
sbJSON.Append(", ");}// Make a string safe for JSONprivatestaticstringSafeJSON(string sIn){StringBuilder sbOut =newStringBuilder(sIn.Length);foreach(char ch in sIn){if(Char.IsControl(ch)|| ch =='\''){int ich =(int)ch;
sbOut.Append(@"\u"+ ich.ToString("x4"));continue;}elseif(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.
Aquí hay un fragmento simple que convierte un XmlNode (recursivamente) en una tabla hash y agrupa varias instancias del mismo hijo en una matriz (como ArrayList). La tabla hash generalmente se acepta para convertir en JSON por la mayoría de las bibliotecas JSON.
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:
<parent><child>
Text
</child></parent><parent><child><grandchild>
Text
</grandchild><grandchild>
Text
</grandchild></child><child>
Text
</child></parent>
Respuestas:
Si. Usando la clase JsonConvert que contiene métodos auxiliares para este propósito preciso:
Documentación aquí: Conversión entre JSON y XML con Json.NET
fuente
Sí, puede hacerlo (lo hago), pero tenga en cuenta algunas paradojas al convertir y maneje adecuadamente. No puede ajustarse automáticamente a todas las posibilidades de la interfaz, y hay 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
{}
anidados O en matrices anidadas,[ {} {} ...]
dependiendo de si solo hay uno o más de un elemento hijo 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 esto en algunos (pero no necesariamente todos) los casos.Una nueva actualización cambia esto (Gracias a Jon Story por señalarlo): https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_NullValueHandling.htm
JSON -> XML
Por favor, siéntase libre de mencionar cualquier otro problema que haya notado, he desarrollado mis propias rutinas personalizadas para preparar y limpiar las cadenas a medida que convierto de un lado a otro. Su situación puede o no requerir 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.
fuente
Puede hacer estas conversiones también con .NET Framework:
JSON a XML: mediante System.Runtime.Serialization.Json
XML a JSON: utilizando System.Web.Script.Serialization
fuente
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): hay un desajuste de impedancia estructural y la conversión es con pérdida. Por lo tanto, 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 ambos.
fuente
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:
fuente
Busqué durante mucho tiempo para 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 :
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.
fuente
Aquí está el código completo de c # para convertir xml a json
Para convertir una cadena XML dada a JSON, simplemente llame a la función XmlToJSON () como se muestra a continuación.
fuente
Prueba esta función. Lo acabo de escribir y no he tenido muchas oportunidades de probarlo, pero mis pruebas preliminares son prometedoras.
fuente
Aquí hay un fragmento simple que convierte un XmlNode (recursivamente) en una tabla hash y agrupa varias instancias del mismo hijo en una matriz (como ArrayList). La tabla hash generalmente se acepta para convertir en JSON por la mayoría de las bibliotecas JSON.
fuente
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:
JSON -> Xml:
Consulte el artículo de CodeProject para obtener ayuda adicional.
Descargo de responsabilidad: soy el autor de esta biblioteca.
fuente
Me gustó lo que dijo David Brown, pero obtuve la siguiente excepción.
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:
Ejemplo de XML que genera el error:
fuente
He utilizado los siguientes métodos para convertir el JSON a XML
Y
He usado la clase llamada Item para representar los elementos.
Funciona....
fuente
Para convertir
JSON
cadena paraXML
probar esto:Para convertir
XML
aJSON
probar esto:fuente
use una biblioteca de terceros, en lugar de escribir código propio para analizar cadenas JSON o XML. Si es un uso único, intente convertirlo en línea. Json a Xml https://www.easycodeforall.com/Json2Xml.jsp Xml a Json https://www.easycodeforall.com/Xml2Json.jsp
fuente