Como converter JSON para XML ou XML para JSON?

Comecei a usar Json.NET para converter uma string no formato JSON para objeto ou viceversa. Não tenho a certeza Json.NET framework, é possível converter uma string em JSON para o formato XML e viceversa?

Author: Termininja, 2009-05-02

12 answers

Sim. Usando a classe JsonConvert que contém métodos auxiliares para este fim 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);

Documentação aqui: converter entre JSON e XML com Json.NET

 370
Author: David Brown, 2014-02-05 10:27:37

Sim, você Pode fazê-lo (eu faço) mas estar ciente de alguns paradoxos ao converter, e lidar adequadamente. Você não pode se conformar automaticamente a todas as possibilidades de interface, e há um suporte embutido limitado no controle da conversão-muitas estruturas e valores JSON não podem ser convertidos automaticamente de ambas as maneiras. Tenha em mente que estou a usar a configuração predefinida com a biblioteca JSON Newtonsoft e a biblioteca XML MS, para que a sua quilometragem possa variar:

XML - > JSON

  1. Todos dados torna-se dados de seqüência de caracteres (por exemplo, você sempre terá "false" não falso ou "0" não 0) Obviamente JavaScript trata estes de forma diferente, em certos casos.
  2. os elementos filhos podem tornar-se objecto aninhado {} ou matriz aninhada [ {} {} ...] dependendo se existir apenas um ou mais elementos-filhos XML. Você consumiria estes dois de forma diferente em JavaScript, etc. Diferentes exemplos de XML em conformidade com o mesmo esquema podem produzir realmente diferentes As estruturas JSON são por aqui. Você pode adicionar o atributo json:Array='true' para o seu elemento para solucionar isso em algumas (mas não necessariamente todos) dos casos.
  3. seu XML deve serrazoavelmente bem formado, eu notei que ele não precisa estar perfeitamente em conformidade com o padrão W3C, mas 1. você deve ter um elemento raiz e 2. você não pode iniciar nomes de elementos com números são duas das normas XML aplicadas que eu encontrei ao usar bibliotecas Newtonsoft e MS.
  4. Em Branco elementos não se convertem a JSON. São ignorados. Um elemento em branco não se torna "elemento": null

JSON - > XML

  1. você precisa de um objeto de nível superior que irá converter para um elemento XML de raiz ou o analisador irá falhar.
  2. os nomes dos seus objectos não podem começar com um número, uma vez que não podem ser convertidos para elementos (o XML é tecnicamente ainda mais rigoroso do que isto), mas eu posso 'escapar' com a quebra de algumas das outras regras de nomenclatura de elementos.
Por favor. sinta-se livre para mencionar quaisquer outras questões que você tenha notado, eu desenvolvi minhas próprias rotinas personalizadas para preparar e limpar as cordas à medida que eu converto para trás e para a frente. A sua situação pode ou não pedir preparação/limpeza. Como StaxMan menciona, sua situação pode realmente exigir que você converta entre objetos...isso poderia implicar interfaces apropriadas e um monte de casos de declarações/etc para lidar com as advertências que mencionei acima.
 35
Author: montewhizdoh, 2018-04-20 19:34:20

Você pode fazer estas conversões também com o Framework. net:

JSON para XML: usando o sistema .Execucao.Seriacao.Json

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

XML para JSON: usando o sistema .Site.Roteiro.Serialização

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 } };
}
 26
Author: Termininja, 2016-05-22 05:20:49
Obrigado pela resposta do David Brown. No meu caso de JSON.Net 3.5, os métodos de conversão estão sob a classe 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);
 26
Author: David.Chu.ca, 2016-08-10 17:09:51

Eu Não tenho certeza de que haja ponto em tal conversão (sim, muitos o fazem, mas principalmente para forçar um peg quadrado através do buraco redondo) -- há desajustamento estrutural de impedância, e a conversão é lossinha. Então eu recomendaria contra tais transformações formato-a-formato.

Mas se o fizer, primeiro converta de json para objecto, depois de objecto para xml (e vice-versa para a direcção inversa). Fazer a transformação direta leva a saída feia, perda de informação, ou possivelmente ambos.

 22
Author: StaxMan, 2012-05-16 19:34:55
Procurei por muito tempo encontrar um código alternativo para a solução aceite, na esperança de não usar uma montagem/projecto externo. Eu inventei o seguinte, graças ao código fonte do projeto 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: eu queria um XmlDocument em vez de um XElement para fins de xPath. Além disso, este código obviamente só vai de JSON para XML, existem várias maneiras de fazer o oposto.

 8
Author: yourbuddypal, 2016-04-04 20:43:08

Aqui está o código c# completo para converter xml para 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 converter uma dada cadeia de XML para JSON, basta chamar a função XmlToJSON () como abaixo.

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" }}
 5
Author: Nimesh khatri, 2016-04-11 06:47:59

Tenta esta função. Acabei de O escrever e não tive grande hipótese de O testar, mas os meus testes preliminares são promissores.

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;
}
 4
Author: Jamon Crockom, 2016-04-21 16:34:46

Aqui está um excerto simples que converte um XmlNode (recursivamente) em uma hashtable, e agrupa várias instâncias do mesmo filho em uma array (como um ArrayList). A Hashtable é geralmente aceita para converter em JSON pela maioria das 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;
}
 2
Author: kronenthaler, 2014-06-06 07:50:34
Fiz o que o David Brown disse, mas tive a seguinte excepção.
$exception {"There are multiple root elements. Line , position ."} System.Xml.XmlException

Uma solução seria modificar o ficheiro XML com um elemento raiz, mas isso nem sempre é necessário e para uma transmissão XML também pode não ser possível. A minha solução abaixo:

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);
            }
        }
    }
}

Exemplo XML que gera o erro:

<parent>
    <child>
        Text
    </child>
</parent>
<parent>
    <child>
        <grandchild>
            Text
        </grandchild>
        <grandchild>
            Text
        </grandchild>
    </child>
    <child>
        Text
    </child>
</parent>
 0
Author: Ogglas, 2017-08-30 09:39:54

Cinchoo ETL - uma biblioteca de código aberto disponíveis para fazer a conversão de Xml para JSON facilmente com poucas linhas 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);
    }
}
Verifique o artigo do CodeProject para obter mais ajuda. Disclaimer: eu sou o autor desta biblioteca.
 0
Author: RajN, 2018-05-01 14:42:01

Usei os métodos abaixo para converter o JSON em 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();
            }
        }

E

        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();
        }

Usei a classe chamada Item para representar os 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....
 0
Author: Sai Ram Sagar, 2018-09-05 13:12:27